?: remove unused mark in grammar rule
[nedit-bw.git] / symbol-lookup.patch
blob087749e2b1997336f7cb20abaf2afd660ce4cd73
1 ---
3 source/interpret.c | 590 +++++++++++++++++++++++++----------------------------
4 source/interpret.h | 27 --
5 source/macro.c | 6
6 source/ops.h | 1
7 source/parse.y | 82 +++----
8 5 files changed, 344 insertions(+), 362 deletions(-)
10 diff --quilt old/source/interpret.c new/source/interpret.c
11 --- old/source/interpret.c
12 +++ new/source/interpret.c
13 @@ -170,7 +170,6 @@ static AccumulatorData *Accumulator;
14 #define ProgP (Accumulator->progP)
15 #define LoopStack (Accumulator->loopStack)
16 #define LoopStackPtr (Accumulator->loopStackPtr)
17 -#define LocalSymList (Accumulator->localSymList)
18 #define ProgramName (Accumulator->name)
20 /* Global data for the interpreter */
21 @@ -212,8 +211,8 @@ static int (*OpFns[])() = {
22 #define FP_GET_PROG(xFrameP) ((FP_GET_ITEM(xFrameP, FP_PROG_INDEX)).val.prog)
23 #define FP_ARG_START_INDEX(xFrameP) (-(FP_GET_ARG_COUNT(xFrameP) + FP_TO_ARGS_DIST))
24 #define FP_GET_ARG_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN + FP_ARG_START_INDEX(xFrameP)))
25 -#define FP_GET_SYM_N(xFrameP,xN) (FP_GET_ITEM(xFrameP, xN))
26 -#define FP_GET_SYM_VAL(xFrameP,xSym) (FP_GET_SYM_N(xFrameP, xSym->value.val.n))
27 +#define FP_GET_SYM_TAB(xFrameP) (FP_GET_ITEM(xFrameP, FP_SYMBOL_TABLE).val.sym)
28 +#define LocalSymList FP_GET_SYM_TAB(Interpreter->frameP)
31 ** Initialize macro language global variables. Must be called before
32 @@ -266,10 +265,9 @@ void InitMacroGlobals(void)
33 AccumulatorData *BeginCreatingProgram(const char *name)
35 AccumulatorData *old = Accumulator;
36 - Accumulator = (AccumulatorData *)XtMalloc(sizeof(*Accumulator));
37 + Accumulator = XtNew(AccumulatorData);
38 memset(Accumulator, 0, sizeof(*Accumulator));
40 - LocalSymList = NULL;
41 ProgP = Prog;
42 LoopStackPtr = LoopStack;
43 ProgramName = name;
44 @@ -285,22 +283,15 @@ AccumulatorData *BeginCreatingProgram(co
45 Program *FinishCreatingProgram(AccumulatorData *old)
47 Program *newProg;
48 - int progLen, fpOffset = 0;
49 - Symbol *s;
50 + int progLen;
52 - newProg = (Program *)XtMalloc(sizeof(Program) + strlen(ProgramName));
53 + newProg = XtNew(Program);
54 + newProg->name = LookupString(ProgramName, True);
55 progLen = ProgP - Prog;
56 - newProg->code = (Inst *)XtMalloc(progLen * sizeof(Inst));
57 + newProg->code = (Inst *)XtCalloc(progLen, sizeof(Inst));
58 memcpy(newProg->code, Prog, progLen * sizeof(Inst));
59 - newProg->localSymList = LocalSymList;
60 - strcpy(newProg->name, ProgramName);
61 newProg->refcount = 1;
63 - /* Local variables' values are stored on the stack. Here we assign
64 - frame pointer offsets to them. */
65 - for (s = newProg->localSymList; s != NULL; s = s->next)
66 - s->value.val.n = fpOffset++;
68 DISASM(newProg->name, newProg->code, ProgP - Prog);
70 XtFree((char *)Accumulator);
71 @@ -312,7 +303,6 @@ Program *FinishCreatingProgram(Accumulat
72 void FreeProgram(Program *prog)
74 if (--prog->refcount == 0) {
75 - freeSymbolList(prog->localSymList);
76 XtFree((char *)prog->code);
77 XtFree((char *)prog);
79 @@ -336,14 +326,14 @@ int AddOp(int op, char **msg)
81 ** Add a symbol operand to the current program
83 -int AddSym(Symbol *sym, char **msg)
84 +int AddSym(const char *sym, char **msg)
86 if (ProgP >= &Prog[PROGRAM_SIZE]) {
87 *msg = "macro too large";
88 return 0;
90 ProgP->type = SYM_INST;
91 - ProgP->val.sym = sym;
92 + ProgP->val.str = sym;
93 ProgP++;
94 return 1;
96 @@ -364,6 +354,21 @@ int AddImmediate(int immed, char **msg)
100 +** Add an string value operand to the current program
102 +int AddString(const char *str, char **msg)
104 + if (ProgP >= &Prog[PROGRAM_SIZE]) {
105 + *msg = "macro too large";
106 + return 0;
108 + ProgP->type = STRING_INST;
109 + ProgP->val.str = str;
110 + ProgP++;
111 + return 1;
115 ** Add a branch offset operand to the current program
117 int AddBranchOffset(Inst *to, char **msg)
118 @@ -507,7 +512,6 @@ static int setupFrame(RestartData *conte
120 static DataValue noValue = {NO_TAG, {0}};
121 int i, totalPushs = 7;
122 - Symbol *s;
125 ** we push only if we have room for the whole frame, so pre-calc the
126 @@ -516,9 +520,6 @@ static int setupFrame(RestartData *conte
127 if (nArgs >= 0) {
128 totalPushs += nArgs;
130 - for (s = prog->localSymList; s != NULL; s = s->next) {
131 - totalPushs++;
134 /* !OK_TO_PUSH(totalPushs) */
135 if (!((context->stackP + totalPushs) <= (context->stack + STACK_SIZE))) {
136 @@ -556,14 +557,14 @@ static int setupFrame(RestartData *conte
137 context->stackP->val.dataval = context->frameP;
138 context->stackP++;
140 - /* symbol table */
141 + /* start a new local symbol list */
142 context->stackP->tag = NO_TAG;
143 - context->stackP->val.sym = prog->localSymList;
144 + context->stackP->val.sym = NULL;
145 context->stackP++;
147 /* macro name */
148 context->stackP->tag = STRING_TAG;
149 - context->stackP->val.str.rep = name;
150 + context->stackP->val.str.rep = (char *)name;
151 context->stackP->val.str.len = strlen(name);
152 context->stackP++;
154 @@ -574,12 +575,6 @@ static int setupFrame(RestartData *conte
156 context->frameP = context->stackP;
158 - /* Initialize and make room on the stack for local variables */
159 - for (s = prog->localSymList; s != NULL; s = s->next) {
160 - FP_GET_SYM_VAL(context->frameP, s) = noValue;
161 - context->stackP++;
164 context->pc = prog->code;
166 return STAT_OK;
167 @@ -592,6 +587,9 @@ static void rewindFrame(RestartData *con
168 DataValue *newFrameP = FP_GET_OLD_FP(context->frameP);
169 Inst *newPC = FP_GET_RET_PC(context->frameP);
170 Program *prog = FP_GET_PROG(context->frameP);
171 + Symbol *symList = FP_GET_SYM_TAB(context->frameP);
173 + freeSymbolList(symList);
175 /* pop past local variables */
176 context->stackP = context->frameP;
177 @@ -636,7 +634,7 @@ int ExecuteMacro(WindowInfo *window, Pro
178 /* Create an execution context (a stack, a stack pointer, a frame pointer,
179 and a program counter) which will retain the program state across
180 preemption and resumption of execution */
181 - context = (RestartData *)XtMalloc(sizeof(RestartData));
182 + context = XtNew(RestartData);
183 memset(context, 0, sizeof(*context));
184 *continuation = context;
185 context->stackP = context->stack;
186 @@ -817,72 +815,12 @@ void SetMacroFocusWindow(WindowInfo *win
191 -** install a list assign (multi-assign) rvalue expression holder into the local
192 -** namespace.
194 -Symbol *InstallMultiAssignExpr(void)
196 - static const char symbolName[] = "list assign expr";
197 - Symbol *sym = LookupSymbol(symbolName);
198 - DataValue value;
199 - value.tag = NO_TAG;
200 - value.val.n = 0;
201 - if (!sym) {
202 - sym = InstallSymbol(symbolName, LOCAL_SYM, value);
204 - return sym;
208 -** Lookup a constant string by its value. This allows reuse of string
209 -** constants and fixing a leak in the interpreter.
211 -Symbol *LookupStringConstSymbol(const char *value)
213 - unsigned int idx;
214 - Symbol *s;
216 - for (idx = 0; idx < GLOBAL_SYMTAB_SIZE; idx++) {
217 - for (s = GlobalSymTab[idx]; s != NULL; s = s->next) {
218 - if (s->type == CONST_SYM
219 - && s->value.tag == STRING_TAG
220 - && !strcmp(s->value.val.str.rep, value)) {
221 - return(s);
226 - return(NULL);
230 -** install string str in the global symbol table with a string name
232 -#define STRING_CONST_SYM_PREFIX "string #"
233 -Symbol *InstallStringConstSymbol(const char *str)
235 - static int stringConstIndex;
236 - char stringName[sizeof(STRING_CONST_SYM_PREFIX) + TYPE_INT_STR_SIZE(int)];
237 - DataValue value;
239 - Symbol *sym = LookupStringConstSymbol(str);
240 - if (sym) {
241 - return sym;
244 - sprintf(stringName, STRING_CONST_SYM_PREFIX "%d", stringConstIndex++);
245 - value.tag = STRING_TAG;
246 - AllocNStringCpy(&value.val.str, str);
247 - return(InstallSymbol(stringName, CONST_SYM, value));
250 static Symbol *lookupSymbol(const Symbol *symlist, const char *name,
251 unsigned int hash)
253 while (NULL != symlist) {
254 if (hash == symlist->hash && strcmp(symlist->name, name) == 0)
255 - return symlist;
256 + return (Symbol *)symlist;
257 symlist = symlist->next;
260 @@ -891,17 +829,20 @@ static Symbol *lookupSymbol(const Symbol
263 ** find a symbol in the symbol table
265 +** will create only LOCAL_SYM and GLOBAL_SYM (depending on first character)
266 +** with a NO_TAG value
268 -Symbol *LookupSymbol(const char *name)
269 +Symbol *LookupSymbol(const char *name, int create)
271 unsigned int hash;
272 - Symbol *s;
273 + Symbol *s = NULL;
275 /* calculate hash for name */
276 hash = hashName(name);
278 /* search in local symbols */
279 - if (Accumulator) {
280 + if (Interpreter) {
281 s = lookupSymbol(LocalSymList, name, hash);
282 if (NULL != s)
283 return s;
284 @@ -912,7 +853,13 @@ Symbol *LookupSymbol(const char *name)
285 if (NULL != s)
286 return s;
288 - return NULL;
289 + if (create) {
290 + DataValue noValue = {NO_TAG, {0}};
291 + s = InstallSymbol(name, name[0] == '$' ? GLOBAL_SYM : LOCAL_SYM,
292 + noValue);
295 + return s;
299 @@ -922,15 +869,23 @@ Symbol *InstallSymbol(const char *name,
301 Symbol *s;
303 - /* no +1, because of .name[1] */
304 - s = malloc(sizeof(Symbol) + strlen(name));
305 - strcpy(s->name, name);
306 + s = XtNew(Symbol);
307 + s->name = LookupString(name, True);
308 s->type = type;
309 s->value = value;
310 s->hash = hashName(s->name);
311 if (type == LOCAL_SYM) {
312 - s->next = LocalSymList;
313 - LocalSymList = s;
314 + if (Interpreter) {
315 + s->next = LocalSymList;
316 + LocalSymList = s;
318 + else {
319 + fprintf(stderr,
320 + "NEdit: try to install local sym without "
321 + "macro context: %s\n", name);
322 + XtFree((char *)s);
323 + s = NULL;
325 } else {
326 addToGlobalSymTab(s);
328 @@ -938,70 +893,6 @@ Symbol *InstallSymbol(const char *name,
332 -** Promote a symbol from local to global, removing it from the local symbol
333 -** list.
335 -** This is used as a forward declaration feature for macro functions.
336 -** If a function is called (ie while parsing the macro) where the
337 -** function isn't defined yet, the symbol is put into the GlobalSymList
338 -** so that the function definition uses the same symbol.
341 -Symbol *PromoteToGlobal(Symbol *sym)
343 - Symbol *s;
345 - if (sym->type != LOCAL_SYM)
346 - return sym;
348 - /* Remove sym from the local symbol list */
349 - if (sym == LocalSymList)
350 - LocalSymList = sym->next;
351 - else {
352 - for (s = LocalSymList; s != NULL; s = s->next) {
353 - if (s->next == sym) {
354 - s->next = sym->next;
355 - break;
360 - /* There are two scenarios which could make this check succeed:
361 - a) this sym is in the GlobalSymList as a LOCAL_SYM symbol
362 - b) there is another symbol as a non-LOCAL_SYM in the GlobalSymList
363 - Both are errors, without question.
364 - We currently just print this warning, but we should error out the
365 - parsing process. */
366 - s = LookupSymbol(sym->name);
367 - if (sym == s) {
368 - /* case a)
369 - just make this symbol a GLOBAL_SYM symbol and return */
370 - fprintf(stderr,
371 - "nedit: To boldly go where no local sym has gone before: %s\n",
372 - sym->name);
373 - sym->type = GLOBAL_SYM;
374 - return sym;
375 - } else if (NULL != s) {
376 - /* case b)
377 - sym will shadow the old symbol from the GlobalSymList */
378 - fprintf(stderr,
379 - "nedit: duplicate symbol in LocalSymList and GlobalSymList: %s\n",
380 - sym->name);
383 - /* Add the symbol directly to the GlobalSymList, because InstallSymbol()
384 - will allocate a new Symbol, which results in a memory leak of sym.
385 - Don't use MACRO_FUNCTION_SYM as type, because in
386 - macro.c:readCheckMacroString() we use ProgramFree() for the .val.prog,
387 - but this symbol has no program attached and ProgramFree() is not NULL
388 - pointer safe */
389 - sym->type = GLOBAL_SYM;
390 - addToGlobalSymTab(sym);
392 - return sym;
396 ** Convert a long value to its decimal string representation, returned in a
397 ** static string.
399 @@ -1171,7 +1062,7 @@ static SparseArrayEntry *allocateSparseA
401 SparseArrayEntryWrapper *mem;
403 - mem = (SparseArrayEntryWrapper *)XtMalloc(sizeof(SparseArrayEntryWrapper));
404 + mem = XtNew(SparseArrayEntryWrapper);
405 mem->next = AllocatedSparseArrayEntries;
406 AllocatedSparseArrayEntries = mem;
407 #ifdef TRACK_GARBAGE_LEAKS
408 @@ -1335,14 +1226,19 @@ static void addToGlobalSymTab(Symbol *sy
410 #define EXEC_ERROR(s1, s2) return execError(s1, s2)
412 -#define GET_SYM(s) \
413 +#define GET_SYM(s, create) \
414 do { \
415 + const char *_n; \
416 if (PC->type != SYM_INST) { \
417 EXEC_ERROR("Unexpected instruction, expected <symbol>: <%s>", \
418 instTypeToStr(PC->type)); \
420 - s = PC->val.sym; \
421 + _n = PC->val.str; \
422 + s = LookupSymbol(_n, create); \
423 PC++; \
424 + if (!s) { \
425 + EXEC_ERROR("No such symbol: %s", _n); \
426 + } \
427 } while (0)
429 #define GET_IMMED(i) \
430 @@ -1365,6 +1261,16 @@ static void addToGlobalSymTab(Symbol *sy
431 PC++; \
432 } while (0)
434 +#define GET_STR(s) \
435 + do { \
436 + if (PC->type != STRING_INST) { \
437 + EXEC_ERROR("Unexpected instruction, expected <string>: <%s>", \
438 + instTypeToStr(PC->type)); \
439 + } \
440 + s = PC->val.str; \
441 + PC++; \
442 + } while (0)
444 #define JUMP(a) \
445 do { \
446 PC = (a); \
447 @@ -1543,11 +1449,9 @@ static int pushSymVal(void)
448 DISASM_RT();
449 STACKDUMP(0, 3);
451 - GET_SYM(s);
452 + GET_SYM(s, False);
454 - if (s->type == LOCAL_SYM) {
455 - symVal = FP_GET_SYM_VAL(FrameP, s);
456 - } else if (s->type == GLOBAL_SYM || s->type == CONST_SYM) {
457 + if (s->type == LOCAL_SYM || s->type == GLOBAL_SYM) {
458 symVal = s->value;
459 } else if (s->type == ARG_SYM) {
460 nArgs = FP_GET_ARG_COUNT(FrameP);
461 @@ -1599,6 +1503,27 @@ static int pushImmed(void)
462 return STAT_OK;
466 +** push string onto the stack
467 +** Before: Prog-> [string], next, ...
468 +** TheStack-> next, ...
469 +** After: Prog-> string, [next], ...
470 +** TheStack-> [string], next, ...
472 +static int pushString(void)
474 + const char *str;
476 + DISASM_RT();
477 + STACKDUMP(0, 3);
479 + GET_STR(str);
481 + PUSH_STRING((char *)str, strlen(str));
483 + return STAT_OK;
486 static int pushArgVal(void)
488 int nArgs, argNum;
489 @@ -1676,18 +1601,13 @@ static int pushArraySymVal(void)
490 DISASM_RT();
491 STACKDUMP(0, 3);
493 - GET_SYM(sym);
494 + GET_SYM(sym, True);
495 GET_IMMED(initEmpty);
497 - if (sym->type == LOCAL_SYM) {
498 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
500 - else if (sym->type == GLOBAL_SYM) {
501 - dataPtr = &sym->value;
503 - else {
504 + if (sym->type != LOCAL_SYM && sym->type != GLOBAL_SYM) {
505 EXEC_ERROR("assigning to non-lvalue array or non-array: %s", sym->name);
507 + dataPtr = &sym->value;
509 if (initEmpty && dataPtr->tag == NO_TAG) {
510 dataPtr->tag = ARRAY_TAG;
511 @@ -1989,7 +1909,7 @@ static int assign(void)
512 DISASM_RT();
513 STACKDUMP(1, 3);
515 - GET_SYM(sym);
516 + GET_SYM(sym, True);
518 if (sym->type != GLOBAL_SYM && sym->type != LOCAL_SYM) {
519 if (sym->type == ARG_SYM) {
520 @@ -2002,13 +1922,7 @@ static int assign(void)
521 EXEC_ERROR("assignment to non-variable: %s", sym->name);
525 - if (sym->type == LOCAL_SYM) {
526 - dataPtr = &FP_GET_SYM_VAL(FrameP, sym);
528 - else {
529 - dataPtr = &sym->value;
531 + dataPtr = &sym->value;
533 POP(value);
535 @@ -2768,7 +2682,7 @@ static int callSubroutine(void)
537 DISASM_RT();
539 - GET_SYM(sym);
540 + GET_SYM(sym, False);
541 GET_IMMED(nArgs);
543 STACKDUMP(nArgs > 0 ? nArgs : -nArgs, 3);
544 @@ -2806,7 +2720,7 @@ static int callSubroutineUnpackArray(voi
546 DISASM_RT();
548 - GET_SYM(sym);
549 + GET_SYM(sym, False);
550 GET_IMMED(nArgs);
552 if (nArgs < 0) {
553 @@ -2910,25 +2824,15 @@ int OverlayRoutineFromSymbol(Symbol *sym
555 int OverlayRoutineFromProg(Program *prog, int nArgs, int removeArgs)
557 - Symbol *sym;
558 - int ret;
559 + Symbol sym;
561 - /* no +1, because of .name[1] */
562 - sym = malloc(sizeof(Symbol) + strlen(prog->name));
563 - if (NULL == sym) {
564 - return STAT_ERROR;
566 + sym.type = MACRO_FUNCTION_SYM;
567 + sym.name = prog->name;
568 + sym.value.tag = NO_TAG;
569 + sym.value.val.prog = prog;
570 + sym.next = NULL;
572 - sym->type = MACRO_FUNCTION_SYM;
573 - strcpy(sym->name, prog->name);
574 - sym->value.val.prog = prog;
575 - sym->next = NULL;
577 - ret = OverlayRoutineFromSymbol(sym, nArgs, removeArgs);
579 - free(sym);
581 - return ret;
582 + return OverlayRoutineFromSymbol(&sym, nArgs, removeArgs);
586 @@ -3627,35 +3531,25 @@ static int arrayIter(void)
587 STACKDUMP(1, 4);
589 GET_IMMED(withVal);
590 - GET_SYM(keySym);
591 + GET_SYM(keySym, True);
592 if (withVal) {
593 - GET_SYM(valSym);
594 + GET_SYM(valSym, True);
596 GET_BRANCH(branchAddr);
598 POP(iterator);
600 - if (keySym->type == LOCAL_SYM) {
601 - keyValPtr = &FP_GET_SYM_VAL(FrameP, keySym);
603 - else if (keySym->type == GLOBAL_SYM) {
604 - keyValPtr = &(keySym->value);
606 - else {
607 + if (keySym->type != LOCAL_SYM && keySym->type != GLOBAL_SYM) {
608 EXEC_ERROR("can't assign to: %s", keySym->name);
610 + keyValPtr = &keySym->value;
611 keyValPtr->tag = NO_TAG;
613 if (withVal) {
614 - if (valSym->type == LOCAL_SYM) {
615 - valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
617 - else if (valSym->type == GLOBAL_SYM) {
618 - valPtr = &(valSym->value);
620 - else {
621 + if (valSym->type != LOCAL_SYM && valSym->type != GLOBAL_SYM) {
622 EXEC_ERROR("can't assign to: %s", valSym->name);
624 + valPtr = &valSym->value;
625 valPtr->tag = NO_TAG;
628 @@ -3794,37 +3688,27 @@ static int arrayIterArray(void)
629 STACKDUMP(2, 4);
631 GET_IMMED(withVal);
632 - GET_SYM(keyArraySym);
633 + GET_SYM(keyArraySym, True);
634 if (withVal) {
635 - GET_SYM(valSym);
636 + GET_SYM(valSym, True);
638 GET_BRANCH(branchAddr);
640 POP(iterator);
641 PEEK_INT(nDims, 0);
643 - if (keyArraySym->type == LOCAL_SYM) {
644 - keyArrayPtr = &FP_GET_SYM_VAL(FrameP, keyArraySym);
646 - else if (keyArraySym->type == GLOBAL_SYM) {
647 - keyArrayPtr = &(keyArraySym->value);
649 - else {
650 + if (keyArraySym->type != LOCAL_SYM && keyArraySym->type != GLOBAL_SYM) {
651 EXEC_ERROR("can't assign to: %s", keyArraySym->name);
653 + keyArrayPtr = &keyArraySym->value;
654 keyArrayPtr->tag = ARRAY_TAG;
655 keyArrayPtr->val.arrayPtr = NULL;
657 if (withVal) {
658 - if (valSym->type == LOCAL_SYM) {
659 - valPtr = &FP_GET_SYM_VAL(FrameP, valSym);
661 - else if (valSym->type == GLOBAL_SYM) {
662 - valPtr = &valSym->value;
664 - else {
665 + if (valSym->type != LOCAL_SYM && valSym->type != GLOBAL_SYM) {
666 EXEC_ERROR("can't assign to: %s", valSym->name);
668 + valPtr = &valSym->value;
669 valPtr->tag = NO_TAG;
672 @@ -4092,6 +3976,108 @@ static int errCheck(const char *s)
676 +** string lookup stuff
679 +/* should be the pagesize */
680 +#define STRING_BLK_SIZE 4096
682 +typedef struct stringEntryTag {
683 + struct stringEntryTag *next;
684 + unsigned int hash;
685 + char str[1]; /* [1] for inUse */
686 +} stringEntry;
688 +struct stringBlkTag;
689 +typedef struct stringBlkHdrTag {
690 + struct stringBlkTag *next;
691 + unsigned size;
692 + unsigned rem;
693 + stringEntry *free;
694 +} stringBlkHdr;
696 +typedef struct stringBlkTag {
697 + stringBlkHdr hdr;
698 + char blk[];
699 +} stringBlk;
701 +static stringBlk *lookupStringBlks;
702 +#define STR_LOOKUP_TAB_SHIFT 10
703 +#define STR_LOOKUP_TAB_SIZE (1u << (STR_LOOKUP_TAB_SHIFT))
704 +#define STR_LOOKUP_TAB_MASK ((STR_LOOKUP_TAB_SIZE) - 1)
705 +static stringEntry *stringTbl[STR_LOOKUP_TAB_SIZE];
707 +const char *LookupString(const char *str, int doInsert)
709 +#define ROUNDUP(x, align) (void *)(-(-((intptr_t)(x)) & -(align)))
710 + unsigned int len = strlen(str) + 1;
711 + unsigned int hash = hashName(str);
712 + unsigned int idx = hash & STR_LOOKUP_TAB_MASK;
713 + stringBlk **blkp = &lookupStringBlks;
714 + stringBlk *blk;
715 + stringEntry *e;
717 + /* search str in hash table */
718 + for (e = stringTbl[idx]; e; e = e->next) {
719 + if (e->hash == hash && 0 == strcmp(str, &e->str[1]))
720 + return &e->str[1];
722 + if (!doInsert) {
723 + return NULL;
726 + /* find space for str */
727 + while (*blkp) {
728 + if ((*blkp)->hdr.rem >= len) {
729 + break;
731 + blkp = &(*blkp)->hdr.next;
733 + blk = *blkp;
735 + /* no space found, create new string bulk */
736 + if (!blk) {
737 + void *ptr;
738 + unsigned size = (unsigned)ROUNDUP(sizeof(stringBlkHdr), sizeof(void *))
739 + + sizeof(stringEntry) + len;
740 + size = (unsigned)ROUNDUP(size, STRING_BLK_SIZE);
742 + posix_memalign(&ptr, STRING_BLK_SIZE, size);
743 + *blkp = blk = ptr;
744 + blk->hdr.size = size;
745 + blk->hdr.next = NULL;
747 + /* round up to sizeof(void *) */
748 + blk->hdr.free = ROUNDUP(blk->blk, sizeof(void *));
749 + blk->hdr.rem = ((char *)blk + blk->hdr.size)
750 + - blk->hdr.free->str - sizeof(stringEntry);
753 + /* mark string as constant and copy str into bulk */
754 + blk->hdr.free->str[1] = 1;
755 + strcpy(&blk->hdr.free->str[1], str);
756 + str = &blk->hdr.free->str[1];
758 + /* insert string into hash table */
759 + blk->hdr.free->next = stringTbl[idx];
760 + blk->hdr.free->hash = hash;
761 + stringTbl[idx] = blk->hdr.free;
763 + /* calculate remaining space */
764 + blk->hdr.free = ROUNDUP((char *)blk->hdr.free + sizeof(stringEntry) + len,
765 + sizeof(void *));
766 + blk->hdr.rem = ((char *)blk + blk->hdr.size) - blk->hdr.free->str;
767 + if (blk->hdr.rem <= sizeof(stringEntry) + 2) {
768 + blk->hdr.rem = 0;
769 + } else {
770 + blk->hdr.rem -= sizeof(stringEntry);
773 + return str;
774 +#undef ROUNDUP
778 ** build a stack dump string, reallocating s as necessary.
780 static char *stackDumpStr(DataValue *fp, const char *msg, char **s, int *pLen)
781 @@ -4129,7 +4115,7 @@ static char *stackDumpStr(DataValue *fp,
782 #endif
783 if (*pLen < len)
785 - *s = *s ? XtRealloc(*s, len) : XtMalloc(len);
786 + *s = XtRealloc(*s, len);
787 *pLen = len;
789 /* now copy */
790 @@ -4270,6 +4256,8 @@ static const char *instTypeToStr(enum in
791 return "operation";
792 case IMMED_INST:
793 return "immediate";
794 + case STRING_INST:
795 + return "string";
796 case BRANCH_INST:
797 return "branch";
798 case SYM_INST:
799 @@ -4352,6 +4340,41 @@ int outPrintd()
800 #endif /* #ifdef DEBUG_DISASSEMBLER */
802 #ifdef DEBUG_DISASSEMBLER /* dumping values in disassembly or stack dump */
803 +static const char *printableString(const char *src, int *shortaged)
805 + int k, l;
806 + static char s[64];
808 + for (k = 0, l = 0; src[k] && l < sizeof s - 1; k++, l++) {
809 + const char *e;
810 + const char to[] = "\\\"ntbrfave";
811 +#ifdef EBCDIC_CHARSET
812 + const char from[] = "\\\"\n\t\b\r\f\a\v\x27"; /* EBCDIC escape */
813 +#else
814 + const char from[] = "\\\"\n\t\b\r\f\a\v\x1B"; /* ASCII escape */
815 +#endif
816 + if ((e = strchr(from, src[k]))) {
817 + if (l < sizeof s - 2) {
818 + s[l++] = '\\';
819 + s[l] = to[e - from];
822 + else if (isprint(src[k])) {
823 + s[l] = src[k];
825 + else {
826 + s[l] = '?';
829 + s[l] = 0;
831 + if (shortaged) {
832 + *shortaged = !!src[k];
835 + return s;
838 static void dumpVal(DataValue dv)
840 printd(" ");
841 @@ -4368,30 +4391,11 @@ static void dumpVal(DataValue dv)
842 printd("<%s NULL>", tagToStr(STRING_TAG));
844 else {
845 - for (k = 0, l = 0; src[k] && l < sizeof s - 1; k++, l++) {
846 - char *e;
847 - const char to[] = "\\\"ntbrfave";
848 -#ifdef EBCDIC_CHARSET
849 - const char from[] = "\\\"\n\t\b\r\f\a\v\x27"; /* EBCDIC escape */
850 -#else
851 - const char from[] = "\\\"\n\t\b\r\f\a\v\x1B"; /* ASCII escape */
852 -#endif
853 - if ((e = strchr(from, src[k]))) {
854 - if (l < sizeof s - 2) {
855 - s[l++] = '\\';
856 - s[l] = to[e - from];
859 - else if (isprint(src[k])) {
860 - s[l] = src[k];
862 - else {
863 - s[l] = '?';
866 - s[l] = 0;
867 - printd("<%s %u:\"%s\"%s>", tagToStr(STRING_TAG),
868 - (unsigned)strlen(src), s, src[k] ? "..." : "");
869 + int cut;
870 + unsigned len = strlen(src);
871 + src = printableString(src, &cut);
872 + printd("<%s %u:\"%s\"%s>", tagToStr(STRING_TAG), len, src,
873 + cut ? "..." : "");
876 break;
877 @@ -4454,13 +4458,23 @@ static void dumpInst(Inst *inst, const c
878 printd(" <%s %d>", name, inst->val.immed);
879 break;
881 + case STRING_INST: {
882 + const char *str = inst->val.str;
883 + int cut;
884 + unsigned len = strlen(str);
885 + str = printableString(str, &cut);
886 + printd(" <%s %u:\"%s\"%s>", name,
887 + len, str, cut ? "..." : "");
889 + break;
891 case BRANCH_INST:
892 printd(" <%s %+td:%8p>", name,
893 inst->val.branch, inst + inst->val.branch);
894 break;
896 case SYM_INST:
897 - printd(" <%s %s>", name, inst->val.sym->name);
898 + printd(" <%s %s>", name, inst->val.str);
899 break;
901 default:
902 @@ -4507,10 +4521,6 @@ static void disasmInternal(Inst *inst, i
903 case OP_ASSIGN:
904 CHECK_OPERANDS(1, SYM_INST);
905 dumpInst(&inst[i+1], NULL);
906 - if (inst[i+1].val.sym->type == CONST_SYM
907 - && inst[i+1].val.sym->value.tag == STRING_TAG) {
908 - dumpVal(inst[i+1].val.sym->value);
910 ++i;
911 break;
913 @@ -4520,6 +4530,12 @@ static void disasmInternal(Inst *inst, i
914 ++i;
915 break;
917 + case OP_PUSH_STRING:
918 + CHECK_OPERANDS(1, STRING_INST);
919 + dumpInst(&inst[i+1], NULL);
920 + ++i;
921 + break;
923 case OP_BRANCH:
924 case OP_BRANCH_TRUE:
925 case OP_BRANCH_FALSE:
926 @@ -4675,11 +4691,6 @@ static void stackdumpframe(DataValue *ar
927 DataValue *endDv = (arg1 > outpt) ? arg1 : outpt;
928 int nArgs = FP_GET_ARG_COUNT(fp);
930 - int nSyms;
931 - static int symLen = 0;
932 - Symbol *syms = FP_GET_ITEM(fp, FP_SYMBOL_TABLE).val.sym;
933 - Symbol *sym;
935 #ifdef DEBUG_STACK_HEADFIRST
936 #else
937 /* do caller's frame */
938 @@ -4688,17 +4699,6 @@ static void stackdumpframe(DataValue *ar
939 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
941 /* do current frame */
942 - /* how many symbols are there? */
943 - for (sym = syms, nSyms = 0; sym != NULL; sym = sym->next) {
944 - nSyms++;
945 - if (symLen < 27) {
946 - int len = strlen(sym->name);
947 - if (len > 27)
948 - len = 27;
949 - if (len > symLen)
950 - symLen = len;
954 /* output instructions between endDv and sp - 1 inclusive */
955 #ifdef DEBUG_STACK_HEADFIRST
956 @@ -4709,7 +4709,6 @@ static void stackdumpframe(DataValue *ar
957 #endif /* #ifdef DEBUG_STACK_HEADFIRST */
959 const char *posFmt = "%-6s";
960 - const char *symName = "";
962 char *pos = "";
963 char buffer[sizeof(STACK_DUMP_ARG_PREFIX) + TYPE_INT_STR_SIZE(int)];
964 @@ -4733,10 +4732,6 @@ static void stackdumpframe(DataValue *ar
965 sprintf(pos = buffer, STACK_DUMP_ARG_PREFIX "%d",
966 offset + FP_TO_ARGS_DIST + nArgs + 1);
968 - else if (0 <= offset && offset < nSyms) {
969 - sprintf(pos = buffer, offset ? "[%d]" : "FP[%d]", offset);
970 - posFmt = "%6s";
972 else if (offset == 0) {
973 pos = "FrameP";
975 @@ -4744,17 +4739,6 @@ static void stackdumpframe(DataValue *ar
977 printd(posFmt, pos);
979 - /* local symbol names? */
980 - if (0 <= offset && offset < nSyms) {
981 - for (sym = syms; sym != NULL; sym = sym->next) {
982 - if (sym->value.val.n == offset) {
983 - symName = sym->name;
984 - break;
988 - printd(" %-*.*s", symLen, symLen, symName);
990 if (dv == fnNm && dv->tag == STRING_TAG && dv->val.str.rep)
991 printd(" %s", dv->val.str.rep);
992 else
993 diff --quilt old/source/interpret.h new/source/interpret.h
994 --- old/source/interpret.h
995 +++ new/source/interpret.h
996 @@ -40,7 +40,7 @@
997 #define LOOP_STACK_SIZE 256 /* (Approx.) Number of break/continue stmts
998 allowed per program */
1000 -enum symTypes {CONST_SYM, GLOBAL_SYM, LOCAL_SYM, ARG_SYM, PROC_VALUE_SYM,
1001 +enum symTypes {GLOBAL_SYM, LOCAL_SYM, ARG_SYM, PROC_VALUE_SYM,
1002 C_FUNCTION_SYM, MACRO_FUNCTION_SYM, ACTION_ROUTINE_SYM};
1004 enum operations {
1005 @@ -54,7 +54,7 @@ enum typeTags {NO_TAG, INT_TAG, STRING_T
1007 enum execReturnCodes {MACRO_TIME_LIMIT, MACRO_PREEMPT, MACRO_DONE, MACRO_ERROR};
1009 -enum instTypes {OP_INST, IMMED_INST, BRANCH_INST, SYM_INST};
1010 +enum instTypes {OP_INST, IMMED_INST, STRING_INST, BRANCH_INST, SYM_INST};
1012 #define ARRAY_DIM_SEP "\034"
1014 @@ -68,8 +68,8 @@ typedef struct InstTag {
1015 union {
1016 enum operations op;
1017 int immed;
1018 + const char *str;
1019 ptrdiff_t branch;
1020 - struct SymbolRec *sym;
1021 } val;
1022 } Inst;
1024 @@ -108,14 +108,13 @@ typedef struct SymbolRec {
1025 DataValue value;
1026 unsigned int hash;
1027 struct SymbolRec *next; /* to link to another */
1028 - char name[1];
1029 + const char *name;
1030 } Symbol;
1032 typedef struct ProgramTag {
1033 - Symbol *localSymList;
1034 + const char *name;
1035 Inst *code;
1036 unsigned refcount;
1037 - char name[1];
1038 } Program;
1040 /* Information needed to re-start a preempted macro */
1041 @@ -131,7 +130,6 @@ typedef struct {
1043 /* state of the accumulator (aka compiler) */
1044 typedef struct AccumulatorDataTag {
1045 - Symbol *localSymList;
1046 Inst prog[PROGRAM_SIZE];
1047 Inst *progP;
1048 Inst *loopStack[LOOP_STACK_SIZE];
1049 @@ -156,25 +154,23 @@ int ArrayCopy(DataValue *dstArray, DataV
1050 AccumulatorData *BeginCreatingProgram(const char *name);
1051 Program *FinishCreatingProgram(AccumulatorData *old);
1052 int AddOp(int op, char **msg);
1053 -int AddSym(Symbol *sym, char **msg);
1054 +int AddSym(const char *str, char **msg);
1055 int AddImmediate(int immed, char **msg);
1056 +int AddString(const char *str, char **msg);
1057 int AddBranchOffset(Inst *to, char **msg);
1058 int SetBranchOffset(Inst *from, Inst *to, char **msg);
1059 Inst *GetPC(void);
1060 -Symbol *InstallIteratorSymbol(void);
1061 -Symbol *LookupStringConstSymbol(const char *value);
1062 -Symbol *InstallStringConstSymbol(const char *str);
1063 -Symbol *LookupSymbol(const char *name);
1064 +Symbol *LookupSymbol(const char *name, int create);
1065 Symbol *InstallSymbol(const char *name, enum symTypes type, DataValue value);
1066 -Symbol *InstallMultiAssignExpr(void);
1067 +const char *LookupString(const char *str, int doInsert);
1068 Inst *SwapCode(Inst *start, Inst *boundary, Inst *end);
1069 int StartLoopAddrList(char **msg);
1070 int AddBreakAddr(Inst *addr, char **msg);
1071 int AddContinueAddr(Inst *addr, char **msg);
1072 void FillLoopAddrs(Inst *breakAddr, Inst *continueAddr);
1074 -/* create a permanently allocated static string (only for use with static strings) */
1075 -#define PERM_ALLOC_STR(xStr) (((char *)("\001" xStr)) + 1)
1076 +/* create a permanently allocated static string */
1077 +#define PERM_ALLOC_STR(xStr) (char *)LookupString(xStr, 1)
1079 /* Routines for executing programs */
1080 int ExecuteMacro(WindowInfo *window, Program *prog, int nArgs, DataValue *args,
1081 @@ -195,7 +191,6 @@ int AllocNStringNCpy(NString *string, co
1082 int AllocNStringCpy(NString *string, const char *s);
1083 void GarbageCollectStrings(void);
1084 void FreeRestartData(RestartData *context);
1085 -Symbol *PromoteToGlobal(Symbol *sym);
1086 void FreeProgram(Program *prog);
1087 void ModifyReturnedValue(RestartData *context, DataValue dv);
1088 WindowInfo *MacroRunWindow(void);
1089 diff --quilt old/source/ops.h new/source/ops.h
1090 --- old/source/ops.h
1091 +++ new/source/ops.h
1092 @@ -7,6 +7,7 @@ OP(RETURN_NO_VAL, returnNoVal)
1093 OP(RETURN, returnVal) /* pop(ret), rewind, push(ret) */
1094 OP(PUSH_SYM, pushSymVal) /* sym */ /* push(sym.v) */
1095 OP(PUSH_IMMED, pushImmed) /* immed */ /* push(immed) */
1096 +OP(PUSH_STRING, pushString) /* str */ /* push(str) */
1097 OP(POP, popStack) /* pop(v) */
1098 OP(DUP, dupStack) /* pop(v), push(v,v) */
1099 OP(ADD, add) /* pop(v2,v1), push(v1 + v2) */
1100 diff --quilt old/source/parse.y new/source/parse.y
1101 --- old/source/parse.y
1102 +++ new/source/parse.y
1103 @@ -41,6 +41,12 @@
1104 return 1; \
1106 } while (0)
1107 +#define ADD_STR(str) \
1108 + do { \
1109 + if (!AddString(str, &ErrMsg)) { \
1110 + return 1; \
1111 + } \
1112 + } while (0)
1113 #define ADD_IMMED(val) \
1114 do { \
1115 if (!AddImmediate(val, &ErrMsg)) { \
1116 @@ -114,7 +120,7 @@ typedef struct LVinst {
1119 %union {
1120 - Symbol *sym;
1121 + const char *str;
1122 Inst *inst;
1123 int num;
1124 enum operations oper;
1125 @@ -124,13 +130,13 @@ typedef struct LVinst {
1126 Symbol *sym;
1127 } define;
1129 -%token <sym> STRING SYMBOL FIELD
1130 +%token <str> STRING SYMBOL FIELD
1131 %token <num> NUMBER
1132 %token DELETE ARG_LOOKUP
1133 %token IF WHILE DO ELSE FOR BREAK CONTINUE RETURN DEFINE TYPEOF KEYVAL
1134 %type <num> arglistopt arglist catlist fnarglsopt fnarglist fnarg
1135 %type <inst> cond comastmts comastmtlst for while do else and or arrayexpr mark
1136 -%type <sym> evalsym
1137 +%type <str> evalsym
1138 %type <define> definesym
1139 %type <oper> operassign incrdecr
1140 %token <oper> '=' ADDEQ SUBEQ MULEQ DIVEQ MODEQ ANDEQ OREQ
1141 @@ -200,31 +206,24 @@ definekw: DEFINE {
1144 definesym: SYMBOL {
1145 - /* we can't really be sure, that we not overwrite any
1146 - ** wrong symbol
1147 - **
1148 - ** we should only overwrite installed MACRO_FUNCTION_SYM
1149 - ** and this is questionable.
1150 - */
1151 - if ($1->type == MACRO_FUNCTION_SYM) {
1152 - FreeProgram($1->value.val.prog);
1153 + $$.sym = LookupSymbol($1, False);
1154 + if ($$.sym) {
1155 + if ($$.sym->type != MACRO_FUNCTION_SYM) {
1156 + yyerror("try to override built-in subroutine"); YYERROR;
1159 - else if ($1->type == LOCAL_SYM ||
1160 - $1->type == GLOBAL_SYM) {
1161 - /* newly created sym, or we overwrite a local sym */;
1162 - } else {
1163 - yyerror("try to override built-in subroutine"); YYERROR;
1164 + else {
1165 + DataValue subrPtr;
1166 + subrPtr.tag = NO_TAG;
1167 + subrPtr.val.prog = NULL;
1168 + $$.sym = InstallSymbol($1, MACRO_FUNCTION_SYM, subrPtr);
1170 - $$.sym = PromoteToGlobal($1);
1171 $$.acc = BeginCreatingProgram($$.sym->name);
1174 define: definekw blank definesym blank blockwb {
1175 ADD_OP(OP_RETURN_NO_VAL);
1176 - Program *prog = FinishCreatingProgram($3.acc);
1177 - $3.sym->type = MACRO_FUNCTION_SYM;
1178 - $3.sym->value.tag = NO_TAG;
1179 - $3.sym->value.val.prog = prog;
1180 + $3.sym->value.val.prog = FinishCreatingProgram($3.acc);
1184 @@ -441,7 +440,8 @@ simpstmt: /* simple variable assignmen
1186 lvlistexpr: '(' lvlist ')' blank '=' blank expr {
1187 /* store expression value */
1188 - ADD_OP(OP_ASSIGN); ADD_SYM(InstallMultiAssignExpr());
1189 + ADD_OP(OP_ASSIGN);
1190 + ADD_SYM(LookupString("list assign expr", True));
1191 /* swap expression evaluation code into position */
1192 SwapCode($2.mid, $2.next, GetPC());
1194 @@ -488,7 +488,8 @@ lventry: mark SYMBOL {
1195 /* Push code: null */
1196 $$.mid = GetPC();
1197 /* Assign code: stack: N, ... */
1198 - ADD_OP(OP_PUSH_SYM); ADD_SYM(InstallMultiAssignExpr());
1199 + ADD_OP(OP_PUSH_SYM);
1200 + ADD_SYM(LookupString("list assign expr", True));
1201 /* stack: E, N, ... */
1202 ADD_OP(OP_SWAP_TOP2); /* stack: N, E, ... */
1203 ADD_OP(OP_ARRAY_REF); ADD_IMMED(1); /* stack: E[N] ... */
1204 @@ -501,7 +502,8 @@ lventry: mark SYMBOL {
1205 /* Push code dealt with in "initarraylv '[' arglist ']'" */
1206 $$.mid = GetPC();
1207 /* Assign code: stack: N, ... */
1208 - ADD_OP(OP_PUSH_SYM); ADD_SYM(InstallMultiAssignExpr());
1209 + ADD_OP(OP_PUSH_SYM);
1210 + ADD_SYM(LookupString("list assign expr", True));
1211 /* stack: E, N, ... */
1212 ADD_OP(OP_SWAP_TOP2); /* stack: N, E, ... */
1213 ADD_OP(OP_ARRAY_REF); ADD_IMMED(1); /* stack: E[N] ... */
1214 @@ -514,7 +516,8 @@ lventry: mark SYMBOL {
1215 /* Push code dealt with in "initarraylv dot field" */
1216 $$.mid = GetPC();
1217 /* Assign code: stack: N, ... */
1218 - ADD_OP(OP_PUSH_SYM); ADD_SYM(InstallMultiAssignExpr());
1219 + ADD_OP(OP_PUSH_SYM);
1220 + ADD_SYM(LookupString("list assign expr", True));
1221 /* stack: E, N, ... */
1222 ADD_OP(OP_SWAP_TOP2); /* stack: N, E, ... */
1223 ADD_OP(OP_ARRAY_REF); ADD_IMMED(1); /* stack: E[N] ... */
1224 @@ -556,18 +559,18 @@ funccall: TYPEOF '(' {
1226 | SYMBOL '(' fnarglsopt ')' {
1227 ADD_OP(OP_SUBR_CALL);
1228 - ADD_SYM(PromoteToGlobal($1)); ADD_IMMED($3);
1229 + ADD_SYM($1); ADD_IMMED($3);
1231 | SYMBOL '(' blank '=' blank expr blank ')' {
1232 /* a single array replaces the argument list */
1233 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
1234 - ADD_SYM(PromoteToGlobal($1));
1235 + ADD_SYM($1);
1236 ADD_IMMED(0); /* zero arguments */
1238 | SYMBOL '(' fnarglist ARGSEP blank '=' blank expr blank ')' {
1239 /* a single array replaces the argument list */
1240 ADD_OP(OP_SUBR_CALL_UNPACK_ARRAY);
1241 - ADD_SYM(PromoteToGlobal($1));
1242 + ADD_SYM($1);
1243 ADD_IMMED($3);
1246 @@ -656,7 +659,7 @@ arraylv: SYMBOL {
1249 field: FIELD {
1250 - ADD_OP(OP_PUSH_SYM); ADD_SYM($1);
1251 + ADD_OP(OP_PUSH_STRING); ADD_STR($1);
1253 /* this bit allows things like array.5 for array[5] **
1254 | NUMBER {
1255 @@ -706,7 +709,7 @@ arrentry: blank {
1257 numexpr: '(' blank expr blank ')'
1258 | NUMBER { ADD_OP(OP_PUSH_IMMED); ADD_IMMED($1); }
1259 - | STRING { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
1260 + | STRING { ADD_OP(OP_PUSH_STRING); ADD_STR($1); }
1261 | SYMBOL { ADD_OP(OP_PUSH_SYM); ADD_SYM($1); }
1262 | funccall {
1263 ADD_OP(OP_FETCH_RET_VAL);
1264 @@ -955,19 +958,17 @@ static int yylex(void)
1265 if (!strcmp(symName, "delete") && follow_non_whitespace('(', SYMBOL, DELETE) == DELETE) return DELETE;
1266 if (!strcmp(symName, "define") && follow_non_whitespace('(', SYMBOL, DEFINE) == DEFINE) return DEFINE;
1267 if (!strcmp(symName, "typeof")) return TYPEOF;
1269 + yylval.str = LookupString(symName, True);
1270 if (nextSymIsField) {
1271 nextSymIsField = 0;
1272 - yylval.sym = InstallStringConstSymbol(symName);
1273 return FIELD;
1275 - if ((s=LookupSymbol(symName)) == NULL) {
1276 - s = InstallSymbol(symName, symName[0]=='$' ?
1277 - (((symName[1] > '0' && symName[1] <= '9') && symName[2] == 0) ?
1278 - ARG_SYM : GLOBAL_SYM) : LOCAL_SYM, value);
1279 - s->value.tag = NO_TAG;
1280 + else {
1281 + return SYMBOL;
1284 - yylval.sym = s;
1285 + yylval.str = LookupString(s->name, True);
1286 return SYMBOL;
1288 nextSymIsField = 0;
1289 @@ -1129,7 +1130,7 @@ static Symbol *matchesActionRoutine(char
1290 if (!hasDash)
1291 return NULL;
1292 *symPtr = '\0';
1293 - s = LookupSymbol(symbolName);
1294 + s = LookupSymbol(symbolName, False);
1295 if (s != NULL)
1296 *inPtr = c;
1297 return s;
1298 @@ -1292,12 +1293,13 @@ static int scanString(void)
1299 if (*InPtr == stopper) {
1300 if (!p) {
1301 /* this was the size measurement and validation */
1302 - p = string = AllocString(len);
1303 + p = string = XtMalloc(len);
1305 else {
1306 /* OK: string now contains our string text */
1307 InPtr++; /* skip past stopper */
1308 - yylval.sym = InstallStringConstSymbol(string);
1309 + yylval.str = LookupString(string, True);
1310 + XtFree(string);
1311 return STRING;
1314 diff --quilt old/source/macro.c new/source/macro.c
1315 --- old/source/macro.c
1316 +++ new/source/macro.c
1317 @@ -3828,7 +3828,7 @@ static int callMS(WindowInfo *window, Da
1318 return False;
1321 - sym = LookupSymbol(fnname);
1322 + sym = LookupSymbol(fnname, False);
1324 if (!sym) {
1325 *errMsg = "subroutine name invalid";
1326 @@ -3906,7 +3906,7 @@ static int defineMS(WindowInfo *window,
1328 XtFree(bodysave);
1330 - sym = LookupSymbol(name);
1331 + sym = LookupSymbol(name, False);
1332 if (sym) {
1333 if (!override) {
1334 FreeProgram(prog);
1335 @@ -7317,7 +7317,7 @@ Boolean MacroApplyHook(WindowInfo *docum
1336 Symbol *hookSymbol;
1337 Boolean succ = False;
1339 - hookSymbol = LookupSymbol(hook);
1340 + hookSymbol = LookupSymbol(hook, False);
1341 if (NULL != hookSymbol && MACRO_FUNCTION_SYM == hookSymbol->type) {
1342 Program *hookProg = hookSymbol->value.val.prog;
1343 RestartData *restartData;