[patch 06/11] call_func()/call_func_with_args() macros
Bert Wesarg
wesarg at informatik.uni-halle.de
Sat Jan 27 16:15:35 CET 2007
This patch isn't realy needed, but with the define_func() macro it
completes the generic macro callback framework
---
source/macro.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 174 insertions(+), 2 deletions(-)
diff --quilt old/source/macro.c new/source/macro.c
--- old/source/macro.c
+++ new/source/macro.c
@@ -410,10 +410,14 @@ static int getStyleAtPosMS(WindowInfo *w
DataValue *result, char **errMsg);
static int filenameDialogMS(WindowInfo* window, DataValue* argList, int nArgs,
DataValue* result, char** errMsg);
static int typeofMS(WindowInfo* window, DataValue* argList, int nArgs,
DataValue* result, char** errMsg);
+static int callFuncMS(WindowInfo *window, DataValue *argList,
+ int nArgs, DataValue *result, char **errMsg);
+static int callFuncWithArgsMS(WindowInfo *window, DataValue *argList,
+ int nArgs, DataValue *result, char **errMsg);
static int dictinsertMS(WindowInfo *window, DataValue *argList, int nArgs,
DataValue *result, char **errMsg);
static int dictcompleteMS(WindowInfo *window, DataValue *argList, int nArgs,
DataValue *result, char **errMsg);
@@ -443,11 +447,12 @@ static BuiltInSubr MacroSubrs[] = {lengt
rangesetGetByNameMS,
getPatternByNameMS, getPatternAtPosMS,
getStyleByNameMS, getStyleAtPosMS, filenameDialogMS,
typeofMS,
dictinsertMS, dictcompleteMS, dictsaveMS,
- dictappendMS, dictiselementMS
+ dictappendMS, dictiselementMS,
+ callFuncMS, callFuncWithArgsMS
};
#define N_MACRO_SUBRS (sizeof MacroSubrs/sizeof *MacroSubrs)
static const char *MacroSubrNames[N_MACRO_SUBRS] = {"length", "get_range", "t_print",
"dialog", "string_dialog", "replace_range", "replace_selection",
"set_cursor_pos", "get_character", "min", "max", "search",
@@ -466,11 +471,12 @@ static const char *MacroSubrNames[N_MACR
"rangeset_get_by_name",
"get_pattern_by_name", "get_pattern_at_pos",
"get_style_by_name", "get_style_at_pos", "filename_dialog",
"typeof",
"dict_insert", "dict_complete", "dict_save",
- "dict_append", "dict_is_element"
+ "dict_append", "dict_is_element",
+ "call_func", "call_func_with_args"
};
static BuiltInSubr SpecialVars[] = {cursorMV, lineMV, columnMV,
fileNameMV, filePathMV, lengthMV, selectionStartMV, selectionEndMV,
selectionLeftMV, selectionRightMV, wrapMarginMV, tabDistMV,
emTabDistMV, useTabsMV, languageModeMV, modifiedMV,
@@ -3554,10 +3560,176 @@ static int filenameDialogMS(WindowInfo*
}
return True;
}
+static int callFuncMS(WindowInfo *window, DataValue *argList,
+ int nArgs, DataValue *result, char **errMsg)
+{
+ char stringStorage[TYPE_INT_STR_SIZE(int)];
+ char *func = NULL;
+ Symbol *sym;
+
+ if (!nArgs) {
+ *errMsg = "subroutine %s called with too few arguments";
+ return False;
+ }
+ if (!readStringArg(argList[0], &func, stringStorage, errMsg)) {
+ return False;
+ }
+
+ /* remove function name from argument list */
+ nArgs--;
+ argList++;
+
+ sym = LookupSymbol(func);
+ if (!sym)
+ {
+ *errMsg = "Function not found.";
+ return False;
+ }
+
+ switch (sym->type) {
+ case MACRO_FUNCTION_SYM:
+ {
+ Program *prog = sym->value.val.prog;
+ RestartData* restartData;
+ int status;
+
+ /* Let 'er rip */
+ status = ExecuteMacro(window, prog, nArgs, argList, result,
+ &restartData, errMsg);
+
+ while (status == MACRO_TIME_LIMIT)
+ {
+ status = ContinueMacro(restartData, result, errMsg);
+ }
+
+ if (status == MACRO_ERROR)
+ {
+ fprintf(stderr, "nedit: \"%s\" error: %s\n", func, *errMsg);
+ return False;
+ }
+
+ return True;
+ }
+ break;
+
+ case C_FUNCTION_SYM:
+ {
+ BuiltInSubr subr = sym->value.val.subr;
+ return subr(window, argList, nArgs, result, errMsg);
+ }
+ break;
+
+ case ACTION_ROUTINE_SYM:
+ {
+ XtActionProc xtproc = sym->value.val.xtproc;
+ String argListString[nArgs];
+ Cardinal nArgsString = 0;
+ XKeyEvent key_event;
+ Display *disp;
+ Window win;
+ int i;
+
+ /* Create a fake event with a timestamp suitable for actions which need
+ timestamps, a marker to indicate that the call was from a macro
+ (to stop shell commands from putting up their own separate banner) */
+ disp = XtDisplay(window->shell);
+ win = XtWindow(window->shell);
+
+ key_event.type = KeyPress;
+ key_event.send_event = MACRO_EVENT_MARKER;
+ key_event.time=XtLastTimestampProcessed(disp);
+
+ /* The following entries are just filled in to avoid problems
+ in strange cases, like calling "self_insert()" directly from the
+ macro menu. In fact the display was sufficient to cure this crash. */
+ key_event.display = disp;
+ key_event.window = key_event.root = key_event.subwindow = win;
+
+ for (i = 0; i < nArgs; i--)
+ {
+ char *stringArg = NULL;
+ if (!readStringArg(argList[i], &stringArg, stringStorage, errMsg))
+ {
+ for (i = 0; i < nArgsString; i++)
+ {
+ free(argListString[i]);
+ }
+ *errMsg = "Try to call an action routine with an none string argument.";
+ return False;
+ }
+ argListString[nArgsString++] = strdup(stringArg);
+ }
+
+ /* Call the action routine */
+ xtproc(window->lastFocus, (XEvent *)&key_event, argListString,
+ &nArgsString);
+
+ for (i = 0; i < nArgsString; i++)
+ {
+ free(argListString[i]);
+ }
+
+ return True;
+ }
+ break;
+
+ default:
+ *errMsg = "Try to call an uncallable function.";
+ return False;
+
+ }
+}
+
+static int callFuncWithArgsMS(WindowInfo *window, DataValue *argList,
+ int nArgs, DataValue *result, char **errMsg)
+{
+ DataValue *argListNew = NULL;
+ int nArgsNew = 0, i;
+ DataValue *args;
+ char keyStorage[TYPE_INT_STR_SIZE(int)];
+ int ret;
+
+ if (nArgs < 1) {
+ *errMsg = "subroutine %s called with too few arguments";
+ return False;
+ }
+ if (nArgs > 2) {
+ *errMsg = "subroutine %s called with too many arguments";
+ return False;
+ }
+ if (argList[1].tag != ARRAY_TAG) {
+ *errMsg = "subroutine %s called with wrong second argument";
+ return False;
+ }
+
+ args = &argList[1];
+ /* one for the function name */
+ nArgsNew = 1 + ArraySize(args);
+
+ argListNew = (DataValue *)XtMalloc(nArgsNew * sizeof(DataValue));
+
+ /* copy the firs arg to new arg, this is the function name */
+ argListNew[0] = argList[0];
+
+ for (i = 1; i < nArgsNew; i++) {
+ sprintf(keyStorage, "%d", i);
+ if (!ArrayGet(args, keyStorage, &argListNew[i])) {
+ *errMsg = "subroutine %s called with wrong array argument";
+ XtFree((char *)argListNew);
+ return False;
+ }
+ }
+
+ ret = callFuncMS(window, argListNew, nArgsNew, result, errMsg);
+ XtFree((char *)argListNew);
+
+ return ret;
+}
+
/* T Balinski */
static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
DataValue *result, char **errMsg)
{
macroCmdInfo *cmdData;
--
More information about the Develop
mailing list