[patch 05/11] Generic macro hook callbacks

Bert Wesarg wesarg at informatik.uni-halle.de
Sat Jan 27 16:15:34 CET 2007


Setup a generic macro hook framework and add the following hooks:
 * in window.c:movedCB()    "cursor_moved_hook"
 * in window.c:modifiedCB() "modified_hook"
 * in window.c:focusCB()    "focus_hook"

---

 source/Makefile.dependencies |    1 
 source/file.c                |   29 ------------
 source/macro.c               |   96 +++++++++++++++++++++++++++++++++++++++++++
 source/macro.h               |    4 +
 source/window.c              |    6 ++
 5 files changed, 109 insertions(+), 27 deletions(-)

diff --quilt old/source/Makefile.dependencies new/source/Makefile.dependencies
--- old/source/Makefile.dependencies
+++ new/source/Makefile.dependencies
@@ -88,5 +88,6 @@ windowTitle.o: windowTitle.c windowTitle
   ../util/clearcase.h
 dictionary.o: dictionary.c dictionary.h ternary_search_tree.h ../util/utils.h
 ternary_search_tree.o: ternary_search_tree.c ternary_search_tree.h
 macro.o: dictionary.h file.h
 menu.o: dictionary.h
+file.o: macro.h
diff --quilt old/source/file.c new/source/file.c
--- old/source/file.c
+++ new/source/file.c
@@ -41,10 +41,11 @@ static const char CVSID[] = "$Id: file.c
 #include "undo.h"
 #include "menu.h"
 #include "tags.h"
 #include "server.h"
 #include "interpret.h"
+#include "macro.h"
 #include "../util/misc.h"
 #include "../util/DialogF.h"
 #include "../util/fileUtils.h"
 #include "../util/getfiles.h"
 #include "../util/printUtils.h"
@@ -173,37 +174,11 @@ WindowInfo *EditNewFile(WindowInfo *inWi
 }
 
 /*  rough hack  */
 static void applyFileOpenHook(const WindowInfo* document)
 {
-    Symbol* fileOpenHookSymbol;
-
-    fileOpenHookSymbol = LookupSymbol("file_open_hook");
-    if (NULL != fileOpenHookSymbol
-            && MACRO_FUNCTION_SYM == fileOpenHookSymbol->type) {
-        Program* hookProg = fileOpenHookSymbol->value.val.prog;
-        DataValue resultDV;
-        RestartData* restartData;
-        int status;
-        char* errMsg;
-
-        /*  Let 'er rip  */
-        status = ExecuteMacro((WindowInfo*) document, hookProg, 0, NULL, &resultDV,
-                &restartData, &errMsg);
-        while (status == MACRO_TIME_LIMIT)
-        {
-            status = ContinueMacro(restartData, &resultDV, &errMsg);
-        }
-
-        if (status == MACRO_PREEMPT || status == MACRO_ERROR)
-        {
-            fprintf(stderr, "nedit: file open hook error: %s\n", (MACRO_ERROR == status) ? errMsg : "No dialogs");
-        } else
-        {
-            /*  Macro is done here  */
-        }
-    }
+    MacroApplyHook(document, "file_open_hook", 0, NULL);
 }
 
 /*
 ** Open an existing file specified by name and path.  Use the window inWindow
 ** unless inWindow is NULL or points to a window which is already in use
diff --quilt old/source/macro.c new/source/macro.c
--- old/source/macro.c
+++ new/source/macro.c
@@ -77,10 +77,11 @@ static const char CVSID[] = "$Id: macro.
 #ifndef __MVS__
 #include <sys/param.h>
 #endif
 #include <fcntl.h>
 #endif /*VMS*/
+#include <stdarg.h>
 
 #include <X11/Intrinsic.h>
 #include <X11/keysym.h>
 #include <Xm/Xm.h>
 #include <Xm/CutPaste.h>
@@ -6137,5 +6138,100 @@ static int dictcompleteMS(WindowInfo *wi
    }
 
    return True;
 }
 /* end of new macros for dictionary  Christian Merkwirth 2000 */
+
+/*  rough hack  */
+void MacroApplyHook(const WindowInfo* document, const char *hook, int argn, DataValue *argv)
+{
+    Symbol* hookSymbol;
+
+    hookSymbol = LookupSymbol(hook);
+    if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
+        Program* hookProg = hookSymbol->value.val.prog;
+        DataValue resultDV;
+        RestartData* restartData;
+        int status;
+        char* errMsg;
+
+        /*  Let 'er rip  */
+        status = ExecuteMacro((WindowInfo*) document, hookProg, argn, argv, &resultDV,
+                &restartData, &errMsg);
+        while (status == MACRO_TIME_LIMIT)
+        {
+            status = ContinueMacro(restartData, &resultDV, &errMsg);
+        }
+
+        if (status == MACRO_PREEMPT || status == MACRO_ERROR)
+        {
+            fprintf(stderr, "nedit: \"%s\" error: %s\n", hook, (MACRO_ERROR == status) ? errMsg : "No dialogs");
+        } else
+        {
+            /*  Macro is done here  */
+        }
+    }
+}
+
+/*  rough hack  */
+void macroVaApplyHook(const WindowInfo* document, const char *hook, ...)
+{
+    DataValue *argv = NULL;
+    va_list ap;
+    enum typeTags tag;
+    int argn = 0, argi = 0, done = 0;
+
+    /* count args for macro */
+    va_start(ap, hook);
+    do
+    {
+        tag = va_arg(ap, enum typeTags);
+        argn++;
+        switch (tag)
+        {
+            case INT_TAG:
+                (void)va_arg(ap, int);
+                break;
+            case STRING_TAG:
+                (void)va_arg(ap, char *);
+                break;
+            case ARRAY_TAG:
+                (void)va_arg(ap, struct SparseArrayEntry *);
+                break;
+            default:
+                argn--;
+                done = 1;
+                break;
+        }
+    } while (!done);
+    va_end(ap);
+    if (argn)
+    {
+        argv = (DataValue *)XtMalloc(argn * sizeof(*argv));
+        va_start(ap, hook);
+        for (argi = 0; argi < argn; argi++)
+        {
+            argv[argi].tag = va_arg(ap, enum typeTags);
+            switch (argv[argi].tag)
+            {
+                case INT_TAG:
+                    argv[argi].val.n = va_arg(ap, int);
+                    break;
+                case STRING_TAG:
+                    argv[argi].val.str.rep = va_arg(ap, char *);
+                    argv[argi].val.str.len = strlen(argv[argi].val.str.rep);
+                    break;
+                case ARRAY_TAG:
+                    argv[argi].val.arrayPtr = va_arg(ap, struct SparseArrayEntry *);
+                    break;
+            }
+        }
+        va_end(ap);
+    }
+
+    MacroApplyHook(document, hook, argn, argv);
+
+    if (argv)
+    {
+        XtFree((char *)argv);
+    }
+}
diff --quilt old/source/macro.h new/source/macro.h
--- old/source/macro.h
+++ new/source/macro.h
@@ -53,7 +53,11 @@ int ReadMacroString(WindowInfo *window, 
 int CheckMacroString(Widget dialogParent, char *string, const char *errIn,
 	char **errPos);
 char *GetReplayMacro(void);
 void ReadMacroInitFile(WindowInfo *window);
 void ReturnShellCommandOutput(WindowInfo *window, const char *outText, int status);
+struct DataValueTag;
+void MacroApplyHook(const WindowInfo* document, const char *hook, int argn, struct DataValueTag *argv);
+void macroVaApplyHook(const WindowInfo* document, const char *hook, ...);
+#define MacroVaApplyHook(doc, hook, ...) macroVaApplyHook(doc, hook, ##__VA_ARGS__, NO_TAG)
 
 #endif /* NEDIT_MACRO_H_INCLUDED */
diff --quilt old/source/window.c new/source/window.c
--- old/source/window.c
+++ new/source/window.c
@@ -2378,10 +2378,12 @@ static void movedCB(Widget w, WindowInfo
     if (0 != textWidget->text.cursorBlinkProcID)
     {
         /*  Start blinking the caret again.  */
         ResetCursorBlink(textWidget, False);
     }
+
+    MacroApplyHook(window, "cursor_moved_hook", 0, NULL);
 }
 
 static void modifiedCB(int pos, int nInserted, int nDeleted, int nRestyled,
         const char *deletedText, void *cbArg) 
 {
@@ -2449,10 +2451,12 @@ static void modifiedCB(int pos, int nIns
     /* Update # of bytes, and line and col statistics */
     UpdateStatsLine(window);
     
     /* Check if external changes have been made to file and warn user */
     CheckForChangesToFile(window);
+
+    MacroApplyHook(window, "modified_hook", 0, NULL);
 }
 
 static void focusCB(Widget w, WindowInfo *window, XtPointer callData) 
 {
     /* record which window pane last had the keyboard focus */
@@ -2464,10 +2468,12 @@ static void focusCB(Widget w, WindowInfo
     /* finish off the current incremental search */
     EndISearch(window);
     
     /* Check for changes to read-only status and/or file modifications */
     CheckForChangesToFile(window);
+
+    MacroApplyHook(window, "focus_hook", 0, NULL);
 }
 
 static void dragStartCB(Widget w, WindowInfo *window, XtPointer callData) 
 {
     /* don't record all of the intermediate drag steps for undo */

-- 



More information about the Develop mailing list