9688a777a961ceeceddcfe70c6c290626408617c
kent
  Fri Aug 9 09:58:26 2019 -0700
Adding fileName and fileLineNumber to strexParseString to make error messages more informative.

diff --git src/lib/strex.c src/lib/strex.c
index c72b1be..79aed4e 100644
--- src/lib/strex.c
+++ src/lib/strex.c
@@ -147,34 +147,35 @@
     { "now", strexBuiltInNow, 0, NULL },
     { "md5", strexBuiltInMd5, 1, oneString },
     { "separate", strexBuiltInSeparate, 3, stringStringInt },
 };
 
 static struct hash *hashBuiltIns()
 /* Build a hash of builtins keyed by name */
 {
 struct hash *hash = hashNew(0);
 int i;
 for (i=0; i<ArraySize(builtins); ++i)
     hashAdd(hash, builtins[i].name, &builtins[i]);
 return hash;
 }
 
-static struct strexIn *strexInNew(char *expression)
+static struct strexIn *strexInNew(char *expression, char *fileName, int fileLineNumber)
 /* Return a new strexIn structure wrapped around expression */
 {
-struct lineFile *lf = lineFileOnString(expression, TRUE, cloneString(expression));
+struct lineFile *lf = lineFileOnString(fileName, TRUE, expression);
+lf->lineIx = fileLineNumber;
 struct tokenizer *tkz = tokenizerOnLineFile(lf);
 tkz->leaveQuotes = TRUE;
 struct strexIn *si;
 AllocVar(si);
 si->tkz = tkz;
 si->builtInHash = hashBuiltIns();
 return si;
 }
 
 static void strexInFree(struct strexIn **pSi)
 /* Free up memory associated with strexIn structure */
 {
 struct strexIn *si = *pSi;
 if (si != NULL)
     {
@@ -679,34 +680,34 @@
 /* Parse out an expression. Leaves input at next expression. */
 {
 return strexParseSum(in);
 }
 
 static void ensureAtEnd(struct strexIn *in)
 /* Make sure that we are at end of input. */
 {
 struct tokenizer *tkz = in->tkz;
 char *leftover = tokenizerNext(tkz);
 if (leftover != NULL)
     errAbort("Extra input starting with '%s' line %d of %s", leftover, tkz->lf->lineIx,
 	tkz->lf->fileName);
 }
 
-struct strexParse *strexParseString(char *s)
+struct strexParse *strexParseString(char *s, char *fileName, int fileLineNumber)
 /* Parse out string expression in s and return root of tree. */
 {
-struct strexIn *si = strexInNew(s);
+struct strexIn *si = strexInNew(s, fileName, fileLineNumber);
 struct strexParse *parseTree = strexParseExpression(si);
 ensureAtEnd(si);
 strexInFree(&si);
 return parseTree;
 }
 
 /* The parsing section is done, now for the evaluation section. */
 
 static struct strexEval strexLocalEval(struct strexParse *p, void *record, StrexEvalLookup lookup, 
 	struct lm *lm);
 /* Evaluate self on parse tree, allocating memory if needed from lm. */
 
 
 static struct strexEval strexEvalCoerceToString(struct strexEval r, char *buf, int bufSize)
 /* Return a version of r with .val.s filled in with something reasonable even