8253c29662c18914cefbcdee22100556fdfb4a95
kent
  Fri Aug 16 00:44:18 2019 -0700
Fixed nasty erratic bug in strip that was erratic and caused by failing to null terminate a string.  Made dots and dashes get turned to underbars in symbolify().  Dumping parse tree at verbosity 2 on the high level string parser.

diff --git src/lib/strex.c src/lib/strex.c
index 577c415..41082c6 100644
--- src/lib/strex.c
+++ src/lib/strex.c
@@ -1095,30 +1095,32 @@
 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, char *fileName, int fileLineNumber,
     void *symbols, StrexLookup lookup)
 /* Parse out string expression in s and return root of tree.  The fileName and
  * fileLineNumber should be filled in with where string came from.  */
 {
 struct lineFile *lf = lineFileOnString(fileName, TRUE, s);
 lf->lineIx = fileLineNumber;
 struct strexIn *si = strexInNew(lf, symbols, lookup);
 struct strexParse *parseTree = strexParseExpression(si);
+if (verboseLevel() >= 2)
+   strexParseDump(parseTree, 1, stderr);
 ensureAtEnd(si);
 strexInFree(&si);
 return parseTree;
 }
 
 struct strexParse *strexParseFile(char *fileName, void *symbols, StrexLookup lookup)
 /* Parse string expression out of a file */
 {
 struct lineFile *lf = lineFileOpen(fileName, TRUE);
 struct strexIn *si = strexInNew(lf, symbols, lookup);
 si->tkz->uncommentShell = TRUE;   // Yay to comments.
 struct strexParse *parseTree = strexParseExpression(si);
 ensureAtEnd(si);
 strexInFree(&si);
 return parseTree;
@@ -1340,31 +1342,31 @@
         return "";
     }
 char *s = words;
 int i;
 for (i=0; ; ++i)
     {
     s = skipLeadingSpaces(s);
     if (isEmpty(s))
 	return "";
     char *end = skipToSpaces(s);
     if (i == ix)
 	{
 	if (end == NULL)
 	    return lmCloneString(lm, s);
 	else
-	    return lmCloneMem(lm, s, end - s);
+	    return lmCloneStringZ(lm, s, end - s);
 	}
     s = end;
     }
 }
 
 static char *uncsvString(char *csvIn,  int ix,  struct lm *lm)
 /* Return the comma separated value of index ix. Memory for result is lm */
 {
 struct dyString *scratch = dyStringNew(0);
 char *one = csvParseOneOut(csvIn, ix, scratch); 
 char *res = emptyForNull(lmCloneString(lm, one));	// Save in more permanent memory
 dyStringFree(&scratch);
 return res;
 }
 
@@ -1417,40 +1419,42 @@
 
 static char *stripAll(char *in, char *toRemove, struct lm *lm)
 /* Remove every occurrence of any of the chars in toRemove from in. */
 {
 char *result = lmCloneString(lm, in);  // Move to local memory
 char c, *s = toRemove;
 while ((c = *s++) != 0)
     stripChar(result, c);
 return result;
 }
 
 static char *symbolify(char *prefix, char *original, struct lm *lm)
 /* Convert original to something could use as a C language symbol with dots maybe. */
 {
 int prefixSize = strlen(prefix);
-char *result = lmAlloc(lm, strlen(original) + prefixSize + 1);  // Move to local memory
-memcpy(result, prefix, prefixSize);
+int originalSize = strlen(original);
+int allocSize = prefixSize + originalSize + 1;
+char *result = lmAlloc(lm, allocSize);  // Move to local memory
+strcpy(result, prefix);
 char *in = skipLeadingSpaces(original); 
 char *out = result + prefixSize;
 char c;
 while ((c = *in++) != 0)
      {
-     if (isspace(c))
+     if (isspace(c) || c == '-' || c == '.')
 	 *out++ = '_';
-     else if (isalnum(c) || c == '.' || c == '_')
+     else if (isalnum(c) || c == '_')
          *out++ = c;
      }
 *out++ = 0;
 int len = strlen(result) - prefixSize;
 if (len > 32)
     {
     char *md5 = hmacMd5("", original);
     strcpy(result + prefixSize, md5);
     freeMem(md5);
     }
 
 return result;
 }
 
 static struct strexEval strexEvalCallBuiltIn(struct strexParse *p,