fd17e3c63508daeec40a961b1ebecbdadafbcfc0
kent
  Tue Aug 20 18:52:11 2019 -0700
Adding a pointer to the symbol table to the warning and abort handler just in case they need a little more context.

diff --git src/lib/strex.c src/lib/strex.c
index dcc0584..f8b2df3 100644
--- src/lib/strex.c
+++ src/lib/strex.c
@@ -1129,42 +1129,42 @@
 si->tkz->uncommentShell = TRUE;   // Yay to comments.
 struct strexParse *parseTree = strexParseExpression(si);
 ensureAtEnd(si);
 strexInFree(&si);
 return parseTree;
 }
 
 /************ The parsing section is done, now for the evaluation section. **************/
 
 struct strexRun
 /* What we need to run a strex expression evaluation */
     {
     void *symbols;	/* Pointer to symbol table */
     StrexLookup lookup; /* Something that can look up things in symbol table */
     struct lm *lm;	/* Local memory for evaluation */
-    void (*warnHandler)(char *warning);  /* Send warning messages here */
-    void (*abortHandler)();	    /* Call this guy to abort */
+    void (*warnHandler)(void *symbols, char *warning);  /* Send warning messages here */
+    void (*abortHandler)(void *symbols);	    /* Call this guy to abort */
     };
 
 static void strexDefaultAbort()
 /* Default abort handler */
 {
 noWarnAbort();
 }
 
 static struct strexRun *strexRunNew(void *symbols, StrexLookup lookup, 
-    void (*warnHandler)(char *warning), void (*abortHandler)() )
+    void (*warnHandler)(void *symbols, char *warning), void (*abortHandler)(void *symbols) )
 /* Return new strexRun structure */
 {
 struct strexRun *run;
 AllocVar(run);
 run->lm = lmInit(0);
 run->symbols = symbols;
 run->lookup = lookup;
 run->warnHandler = warnHandler;
 run->abortHandler = (abortHandler != NULL ? abortHandler : strexDefaultAbort);
 return run;
 }
 
 static void strexRunFree(struct strexRun **pRun)
 /* Free up strex run structure */
 {
@@ -1694,45 +1694,45 @@
 	if (ourEnd == NULL)
 	    ourEnd = defaultEnd;
 
 	int size = ourEnd - ourStart;
 	assert(size >= 0);
 	res.val.s = lmCloneStringZ(lm, ourStart, size);
 	break;
 	}
     case strexBuiltInWarn:
         {
 	/* Figure out the message we want to convey, send it to warning handler
 	 * before returning it. */
         struct strexEval a = strexLocalEval(p->children, run);
 	char *message = a.val.s;
 	char *output = lmJoinStrings(run->lm, "WARNING: ", message);
-	if (run->warnHandler != NULL) run->warnHandler(output);
+	if (run->warnHandler != NULL) run->warnHandler(run->symbols, output);
 	res.val.s = output;
 	break;
 	}
     case strexBuiltInError:
         {
 	/* Figure out the message we want to convey, send it to warning handler
 	 * before returning it. */
         struct strexEval a = strexLocalEval(p->children, run);
 	char *message = a.val.s;
 	char *output = lmJoinStrings(run->lm, "ERROR: ", message);
 	if (run->warnHandler != NULL) 
-	    run->warnHandler(output);
+	    run->warnHandler(run->symbols, output);
 	if (run->abortHandler != NULL) 
-	    run->abortHandler();
+	    run->abortHandler(run->symbols);
 	errAbort("%s", output);
 	res.val.s = output;   // some sort of OCD makes me fill this in in spite of errAbort above
 	break;
 	}
     }
 return res;
 }
 
 static struct strexEval strexEvalPick(struct strexParse *pick, struct strexRun *run)
 /* Evaluate a pick operator. */
 {
 /* Evaluate the keyValue */
 struct strexParse *p = pick->children;
 struct strexEval keyVal = strexLocalEval(p, run);
 p = p->next;
@@ -1924,31 +1924,31 @@
        res = strexEvalAnd(p, run);
        break;
 
     default:
         errAbort("Unknown op %s\n", strexOpToString(p->op));
 	res.type = strexTypeInt;	// Keep compiler from complaining.
 	res.val.i = 0;	// Keep compiler from complaining.
 	break;
     }
 return res;
 }
 
 /* ---- And the one public evaluation function ---- */
 
 char *strexEvalAsString(struct strexParse *p, void *symbols, StrexLookup lookup,
-    void (*warnHandler)(char *warning), void (*abortHandler)() )
+    void (*warnHandler)(void *symbols, char *warning), void (*abortHandler)(void *symbols) )
 /* Return result as a string value.  The warnHandler and abortHandler are optional,
  * and can be used to wrap your own warnings and abort processing onto what strex
  * provides.  For default behavior just pass in NULL. */
 
 {
 /* Set up run time environment for strex and evaluate.*/
 struct strexRun *run = strexRunNew(symbols, lookup, warnHandler, abortHandler);
 struct strexEval res = strexLocalEval(p,run);
 
 /* Convert result to string and copy to memory that'll survive loss of run time environment */
 char numBuf[32];
 struct strexEval strRes = strexEvalCoerceToString(res, numBuf, sizeof(numBuf));
 char *ret = cloneString(strRes.val.s);  
 
 /* Clean up and go home */