use StringToNumEnd() for check of numeric keys
[nedit-bw.git] / global-RestartData.patch
blob4e58695e1b170c7cd4d79c5802a1e3346ab4a434
1 ---
3 source/interpret.c | 186 +++++++++++++++++++++--------------------------------
4 source/interpret.h | 3
5 2 files changed, 78 insertions(+), 111 deletions(-)
7 diff --quilt old/source/interpret.c new/source/interpret.c
8 --- old/source/interpret.c
9 +++ new/source/interpret.c
10 @@ -81,8 +81,7 @@ static const char CVSID[] = "$Id: interp
11 enum opStatusCodes {STAT_OK=2, STAT_DONE, STAT_ERROR, STAT_PREEMPT};
13 static int addLoopAddr(Inst *addr, char **msg);
14 -static void saveContext(RestartData *context);
15 -static void restoreContext(RestartData *context);
16 +static RestartData *setContext(RestartData *context);
18 #define OP(name, fn) static int fn(void);
19 #include "ops.h"
20 @@ -175,16 +174,14 @@ static Inst **LoopStackPtr = LoopStack;
21 static const char *ProgramName = "";
23 /* Global data for the interpreter */
24 -static DataValue *TheStack; /* the stack */
25 -static DataValue *StackP; /* next free spot on stack */
26 -static DataValue *FrameP; /* frame pointer (start of local variables
27 - for the current subroutine invocation) */
28 -static Inst *PC; /* program counter during execution */
29 -static char *ErrMsg; /* global for returning error messages
30 - from executing functions */
31 -static WindowInfo
32 - *InitiatingWindow = NULL; /* window from which macro was run */
33 -static WindowInfo *FocusWindow; /* window on which macro commands operate */
34 +static RestartData *Interpreter;
35 +#define StackP (Interpreter->stackP)
36 +#define TheStack (Interpreter->stack)
37 +#define FrameP (Interpreter->frameP)
38 +#define PC (Interpreter->pc)
39 +#define InitiatingWindow (Interpreter->runWindow)
40 +#define FocusWindow (Interpreter->focusWindow)
41 +#define ErrMsg (Interpreter->errMsg)
42 static int PreemptRequest; /* passes preemption requests from called
43 routines back up to the interpreter */
45 @@ -532,7 +529,7 @@ static int setupFrame(RestartData *conte
48 /* !OK_TO_PUSH(totalPushs) */
49 - if (!((context->stackP + totalPushs) <= &context->stack[STACK_SIZE])) {
50 + if (!((context->stackP + totalPushs) <= (context->stack + STACK_SIZE))) {
51 return execError(StackOverflowMsg, "");
54 @@ -596,30 +593,30 @@ static int setupFrame(RestartData *conte
55 return STAT_OK;
58 -static Inst *rewindFrame(DataValue **frameP, DataValue **stackP)
59 +static void rewindFrame(RestartData *context)
61 /* get stored return information */
62 - int nArgs = FP_GET_ARG_COUNT(*frameP);
63 - DataValue *newFrameP = FP_GET_OLD_FP(*frameP);
64 - Inst *newPC = FP_GET_RET_PC(*frameP);
65 - Program *prog = FP_GET_PROG(*frameP);
66 + int nArgs = FP_GET_ARG_COUNT(context->frameP);
67 + DataValue *newFrameP = FP_GET_OLD_FP(context->frameP);
68 + Inst *newPC = FP_GET_RET_PC(context->frameP);
69 + Program *prog = FP_GET_PROG(context->frameP);
71 /* pop past local variables */
72 - *stackP = *frameP;
73 + context->stackP = context->frameP;
74 /* pop past arguments */
75 - *stackP -= (FP_TO_ARGS_DIST + nArgs);
76 + context->stackP -= (FP_TO_ARGS_DIST + nArgs);
78 - *frameP = newFrameP;
79 + context->frameP = newFrameP;
81 FreeProgram(prog);
83 - return newPC;
84 + context->pc = newPC;
87 static void rewindStack(RestartData *context)
89 while (context->pc) {
90 - context->pc = rewindFrame(&context->frameP, &context->stackP);
91 + rewindFrame(context);
95 @@ -648,7 +645,7 @@ int ExecuteMacro(WindowInfo *window, Pro
96 and a program counter) which will retain the program state across
97 preemption and resumption of execution */
98 context = (RestartData *)XtMalloc(sizeof(RestartData));
99 - context->stack = (DataValue *)XtMalloc(sizeof(DataValue) * STACK_SIZE);
100 + memset(context, 0, sizeof(*context));
101 *continuation = context;
102 context->stackP = context->stack;
103 context->runWindow = window;
104 @@ -679,18 +676,17 @@ int ContinueMacro(RestartData *continuat
106 register int status, instCount = 0;
107 register Inst *inst;
108 - RestartData oldContext;
110 - /* To allow macros to be invoked arbitrarily (such as those automatically
111 - triggered within smart-indent) within executing macros, this call is
112 - reentrant. */
113 - saveContext(&oldContext);
114 + RestartData *oldContext;
117 + ** To allow macros to be invoked arbitrarily (such as those automatically
118 + ** triggered within smart-indent) within executing macros, this call is
119 + ** reentrant.
120 + **
121 ** Execution Loop: Call the succesive routine addresses in the program
122 ** until one returns something other than STAT_OK, then take action
124 - restoreContext(continuation);
125 + oldContext = setContext(continuation);
126 ErrMsg = NULL;
127 for (;;) {
129 @@ -715,21 +711,18 @@ int ContinueMacro(RestartData *continuat
130 /* If error return was not STAT_OK, return to caller */
131 if (status != STAT_OK) {
132 if (status == STAT_PREEMPT) {
133 - saveContext(continuation);
134 - restoreContext(&oldContext);
135 + setContext(oldContext);
136 return MACRO_PREEMPT;
137 } else if (status == STAT_ERROR) {
138 *msg = ErrMsg;
139 - saveContext(continuation);
140 + setContext(oldContext);
141 FreeRestartData(continuation);
142 - restoreContext(&oldContext);
143 return MACRO_ERROR;
144 } else if (status == STAT_DONE) {
145 *msg = "";
146 *result = *--StackP;
147 - saveContext(continuation);
148 + setContext(oldContext);
149 FreeRestartData(continuation);
150 - restoreContext(&oldContext);
151 return MACRO_DONE;
154 @@ -739,8 +732,7 @@ int ContinueMacro(RestartData *continuat
155 X, other macros, and other shell scripts a chance to execute */
156 instCount++;
157 if (instCount >= INSTRUCTION_LIMIT) {
158 - saveContext(continuation);
159 - restoreContext(&oldContext);
160 + setContext(oldContext);
161 return MACRO_TIME_LIMIT;
164 @@ -776,7 +768,6 @@ int RunMacroAsSubrCall(RestartData *cont
165 void FreeRestartData(RestartData *context)
167 rewindStack(context);
168 - XtFree((char *)context->stack);
169 XtFree((char *)context);
172 @@ -797,8 +788,8 @@ void PreemptMacro(void)
174 void ModifyReturnedValue(RestartData *context, DataValue dv)
176 - if ((context->pc-1)->val.op == OP_FETCH_RET_VAL)
177 - *(context->stackP-1) = dv;
178 + if ((context->pc - 1)->val.op == OP_FETCH_RET_VAL)
179 + *(context->stackP - 1) = dv;
183 @@ -807,7 +798,7 @@ void ModifyReturnedValue(RestartData *co
185 WindowInfo *MacroRunWindow(void)
187 - return InitiatingWindow;
188 + return Interpreter ? InitiatingWindow : NULL;
192 @@ -817,7 +808,7 @@ WindowInfo *MacroRunWindow(void)
194 WindowInfo *MacroFocusWindow(void)
196 - return FocusWindow;
197 + return Interpreter ? FocusWindow : NULL;
201 @@ -826,7 +817,12 @@ WindowInfo *MacroFocusWindow(void)
203 void SetMacroFocusWindow(WindowInfo *window)
205 - FocusWindow = window;
206 + if (Interpreter) {
207 + FocusWindow = window;
209 + else {
210 + fprintf(stderr, "NEdit: setting FocusWindow while not running a macro\n");
215 @@ -1319,24 +1315,11 @@ void GarbageCollectStrings(void)
217 ** Save and restore execution context to data structure "context"
219 -static void saveContext(RestartData *context)
220 +static RestartData *setContext(RestartData *new)
222 - context->stack = TheStack;
223 - context->stackP = StackP;
224 - context->frameP = FrameP;
225 - context->pc = PC;
226 - context->runWindow = InitiatingWindow;
227 - context->focusWindow = FocusWindow;
230 -static void restoreContext(RestartData *context)
232 - TheStack = context->stack;
233 - StackP = context->stackP;
234 - FrameP = context->frameP;
235 - PC = context->pc;
236 - InitiatingWindow = context->runWindow;
237 - FocusWindow = context->focusWindow;
238 + RestartData *old = Interpreter;
239 + Interpreter = new;
240 + return old;
243 static void freeSymbolList(Symbol *symList)
244 @@ -1423,17 +1406,6 @@ static void addToGlobalSymTab(Symbol *sy
246 } while (0)
248 -#define FRAME_GET_ITEM(xIndex) FP_GET_ITEM(FrameP,xIndex)
249 -#define FRAME_GET_ARG_ARRAY() FP_GET_ARG_ARRAY(FrameP)
250 -#define FRAME_GET_ARG_COUNT() FP_GET_ARG_COUNT(FrameP)
251 -#define FRAME_GET_OLD_FP() FP_GET_OLD_FP(FrameP)
252 -#define FRAME_GET_RET_PC() FP_GET_RET_PC(FrameP)
253 -#define FRAME_GET_PROG() FP_GET_PROG(FrameP)
254 -#define FRAME_ARG_START_INDEX() FP_ARG_START_INDEX(FrameP)
255 -#define FRAME_GET_ARG_N(xN) FP_GET_ARG_N(FrameP,xN)
256 -#define FRAME_GET_SYM_N(xN) FP_GET_SYM_N(FrameP,xN)
257 -#define FRAME_GET_SYM_VAL(xSym) FP_GET_SYM_VAL(FrameP,xSym)
259 /* true, if you can pop n values */
260 #define OK_TO_POP(n) \
261 ((StackP - (n)) >= TheStack)
262 @@ -1447,7 +1419,7 @@ static void addToGlobalSymTab(Symbol *sy
264 /* true, if you can push n values */
265 #define OK_TO_PUSH(n) \
266 - (StackP + (n) <= &TheStack[STACK_SIZE])
267 + (StackP + (n) <= (TheStack + STACK_SIZE))
269 #define PUSH_CHECK(n) \
270 do { \
271 @@ -1599,11 +1571,11 @@ static int pushSymVal(void)
272 GET_SYM(s);
274 if (s->type == LOCAL_SYM) {
275 - symVal = FRAME_GET_SYM_VAL(s);
276 + symVal = FP_GET_SYM_VAL(FrameP, s);
277 } else if (s->type == GLOBAL_SYM || s->type == CONST_SYM) {
278 symVal = s->value;
279 } else if (s->type == ARG_SYM) {
280 - nArgs = FRAME_GET_ARG_COUNT();
281 + nArgs = FP_GET_ARG_COUNT(FrameP);
282 argNum = s->value.val.n;
283 if (argNum >= nArgs) {
284 EXEC_ERROR("referenced undefined argument: %s", s->name);
285 @@ -1613,12 +1585,11 @@ static int pushSymVal(void)
286 symVal.val.n = nArgs;
288 else {
289 - symVal = FRAME_GET_ARG_N(argNum);
290 + symVal = FP_GET_ARG_N(FrameP, argNum);
292 } else if (s->type == PROC_VALUE_SYM) {
293 - char *errMsg;
294 - if (!(s->value.val.subr)(FocusWindow, NULL, 0,
295 - &symVal, &errMsg)) {
296 + char *errMsg;
297 + if (!s->value.val.subr(FocusWindow, NULL, 0, &symVal, &errMsg)) {
298 EXEC_ERROR(errMsg, s->name);
300 } else if (s->type == C_FUNCTION_SYM
301 @@ -1667,12 +1638,12 @@ static int pushArgVal(void)
303 POP_INT(argNum);
304 --argNum;
305 - nArgs = FRAME_GET_ARG_COUNT();
306 + nArgs = FP_GET_ARG_COUNT(FrameP);
307 if (argNum >= nArgs || argNum < 0) {
308 EXEC_ERROR("referenced undefined argument: $args[%s]",
309 longAsStr(argNum + 1));
311 - PUSH(FRAME_GET_ARG_N(argNum));
312 + PUSH(FP_GET_ARG_N(FrameP, argNum));
313 return STAT_OK;
316 @@ -1681,7 +1652,7 @@ static int pushArgCount(void)
317 DISASM_RT();
318 STACKDUMP(0, 3);
320 - PUSH_INT(FRAME_GET_ARG_COUNT());
321 + PUSH_INT(FP_GET_ARG_COUNT(FrameP));
322 return STAT_OK;
325 @@ -1694,8 +1665,8 @@ static int pushArgArray(void)
326 DISASM_RT();
327 STACKDUMP(0, 3);
329 - nArgs = FRAME_GET_ARG_COUNT();
330 - argArray = &FRAME_GET_ARG_ARRAY();
331 + nArgs = FP_GET_ARG_COUNT(FrameP);
332 + argArray = &FP_GET_ARG_ARRAY(FrameP);
333 if (argArray->tag != ARRAY_TAG) {
334 /* we require a real array in the argArray position */
335 argArray->tag = ARRAY_TAG;
336 @@ -1706,7 +1677,7 @@ static int pushArgArray(void)
337 if (needArgCopy || (nArgs && !ArrayGet(argArray, (char *)"1", &argVal))) {
338 /* load arguments from positional arg list if not already done */
339 for (argNum = 0; argNum < nArgs; ++argNum) {
340 - argVal = FRAME_GET_ARG_N(argNum);
341 + argVal = FP_GET_ARG_N(FrameP, argNum);
342 if (!ArrayInsert(argArray, AllocStringOfNumber(argNum + 1),
343 &argVal)) {
344 EXEC_ERROR("argument array insertion failure", NULL);
345 @@ -1739,7 +1710,7 @@ static int pushArraySymVal(void)
346 GET_IMMED(initEmpty);
348 if (sym->type == LOCAL_SYM) {
349 - dataPtr = &FRAME_GET_SYM_VAL(sym);
350 + dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
352 else if (sym->type == GLOBAL_SYM) {
353 dataPtr = &sym->value;
354 @@ -2063,7 +2034,7 @@ static int assign(void)
357 if (sym->type == LOCAL_SYM) {
358 - dataPtr = &FRAME_GET_SYM_VAL(sym);
359 + dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
361 else {
362 dataPtr = &sym->value;
363 @@ -2388,8 +2359,8 @@ static int eq(void)
364 /* negated eq() call */
365 static int ne(void)
367 - eq();
368 - return not();
369 + int status = eq();
370 + return (status == STAT_OK) ? not() : status;
374 @@ -2719,7 +2690,6 @@ static int callSubroutineFromSymbol(Symb
375 static DataValue noValue = {NO_TAG, {0}};
376 DataValue argArray = noValue;
377 Program *prog;
378 - char *errMsg;
379 int haveNamedArgs = (nArgs < 0);
380 DataValue *symValPtr = NULL;
382 @@ -2729,7 +2699,7 @@ static int callSubroutineFromSymbol(Symb
385 if (sym->type == LOCAL_SYM) {
386 - symValPtr = &FRAME_GET_SYM_VAL(sym);
387 + symValPtr = &FP_GET_SYM_VAL(FrameP, sym);
388 } else if (sym->type == GLOBAL_SYM) {
389 symValPtr = &sym->value;
391 @@ -2747,6 +2717,7 @@ static int callSubroutineFromSymbol(Symb
393 if (sym->type == C_FUNCTION_SYM) {
394 DataValue result;
395 + char *errMsg;
397 PUSH(argArray); /* push dummy named arg array */
399 @@ -2755,9 +2726,9 @@ static int callSubroutineFromSymbol(Symb
401 /* Call the function and check for preemption */
402 PreemptRequest = False;
403 - if (!sym->value.val.subr(FocusWindow, StackP,
404 - nArgs, &result, &errMsg))
405 + if (!sym->value.val.subr(FocusWindow, StackP, nArgs, &result, &errMsg)) {
406 EXEC_ERROR(errMsg, sym->name);
408 PUSH_RET_VAL(result);
409 return PreemptRequest ? STAT_PREEMPT : STAT_OK;
411 @@ -2770,15 +2741,10 @@ static int callSubroutineFromSymbol(Symb
412 ** values which are already there.
414 if (sym->type == MACRO_FUNCTION_SYM) {
415 - RestartData context;
416 - int status;
417 prog = sym->value.val.prog;
418 prog->refcount++;
419 /* -nArgs means 'arguments are on stack' */
420 - saveContext(&context);
421 - status = setupFrame(&context, prog, -nArgs, NULL, argArray, sym->name);
422 - restoreContext(&context);
423 - return status;
424 + return setupFrame(Interpreter, prog, -nArgs, NULL, argArray, sym->name);
428 @@ -3044,7 +3010,7 @@ static int returnValOrNone(int valOnStac
429 static DataValue noValue = {NO_TAG, {0}};
431 DISASM_RT();
432 - STACKDUMP(StackP - FrameP + FRAME_GET_ARG_COUNT() + FP_TO_ARGS_DIST, 3);
433 + STACKDUMP(StackP - FrameP + FP_GET_ARG_COUNT(FrameP) + FP_TO_ARGS_DIST, 3);
435 /* return value is on the stack */
436 if (valOnStack) {
437 @@ -3054,7 +3020,7 @@ static int returnValOrNone(int valOnStac
438 retVal = noValue;
441 - PC = rewindFrame(&FrameP, &StackP);
442 + rewindFrame(Interpreter);
444 /* push returned value, if requsted */
445 PUSH_RET_VAL(retVal);
446 @@ -3661,7 +3627,7 @@ static int beginArrayIter(void)
447 POP(arrayVal);
449 if (iterator->type == LOCAL_SYM) {
450 - iteratorValPtr = &FRAME_GET_SYM_VAL(iterator);
451 + iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
453 else {
454 EXEC_ERROR("bad temporary iterator: %s", iterator->name);
455 @@ -3724,7 +3690,7 @@ static int arrayIter(void)
456 GET_BRANCH(branchAddr);
458 if (keySym->type == LOCAL_SYM) {
459 - keyValPtr = &FRAME_GET_SYM_VAL(keySym);
460 + keyValPtr = &FP_GET_SYM_VAL(FrameP, keySym);
462 else if (keySym->type == GLOBAL_SYM) {
463 keyValPtr = &(keySym->value);
464 @@ -3736,7 +3702,7 @@ static int arrayIter(void)
466 if (withVal) {
467 if (valSym->type == LOCAL_SYM) {
468 - valPtr = &FRAME_GET_SYM_VAL(valSym);
469 + valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
471 else if (valSym->type == GLOBAL_SYM) {
472 valPtr = &(valSym->value);
473 @@ -3748,7 +3714,7 @@ static int arrayIter(void)
476 if (iterator->type == LOCAL_SYM) {
477 - iteratorValPtr = &FRAME_GET_SYM_VAL(iterator);
478 + iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
480 else {
481 EXEC_ERROR("bad temporary iterator: %s", iterator->name);
482 @@ -3797,7 +3763,7 @@ static int beginArrayIterArray(void)
483 PEEK_INT(nDims, 0);
485 if (iterator->type == LOCAL_SYM) {
486 - iteratorValPtr = &FRAME_GET_SYM_VAL(iterator);
487 + iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
489 else {
490 EXEC_ERROR("bad temporary iterator: %s", iterator->name);
491 @@ -3904,7 +3870,7 @@ static int arrayIterArray(void)
492 PEEK_INT(nDims, 0);
494 if (keyArraySym->type == LOCAL_SYM) {
495 - keyArrayPtr = &FRAME_GET_SYM_VAL(keyArraySym);
496 + keyArrayPtr = &FP_GET_SYM_VAL(FrameP, keyArraySym);
498 else if (keyArraySym->type == GLOBAL_SYM) {
499 keyArrayPtr = &(keyArraySym->value);
500 @@ -3917,7 +3883,7 @@ static int arrayIterArray(void)
502 if (withVal) {
503 if (valSym->type == LOCAL_SYM) {
504 - valPtr = &FRAME_GET_SYM_VAL(valSym);
505 + valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
507 else if (valSym->type == GLOBAL_SYM) {
508 valPtr = &valSym->value;
509 @@ -3929,7 +3895,7 @@ static int arrayIterArray(void)
512 if (iterator->type == LOCAL_SYM) {
513 - iteratorValPtr = &FRAME_GET_SYM_VAL(iterator);
514 + iteratorValPtr = &FP_GET_SYM_VAL(FrameP, iterator);
516 else {
517 EXEC_ERROR("bad temporary iterator: %s", iterator->name);
518 diff --quilt old/source/interpret.h new/source/interpret.h
519 --- old/source/interpret.h
520 +++ new/source/interpret.h
521 @@ -121,12 +121,13 @@ typedef struct ProgramTag {
523 /* Information needed to re-start a preempted macro */
524 typedef struct {
525 - DataValue *stack;
526 + DataValue stack[STACK_SIZE];
527 DataValue *stackP;
528 DataValue *frameP;
529 Inst *pc;
530 WindowInfo *runWindow;
531 WindowInfo *focusWindow;
532 + char *errMsg;
533 } RestartData;
535 /* state of the accumulator (aka compiler) */