c42b06abab5a57ec60a8c43f4bb531681f2a5612
kent
  Sat Aug 17 13:24:29 2019 -0700
Implemented error() built in for the run time abort.

diff --git src/lib/strex.c src/lib/strex.c
index 5312ef3..1ff4962 100644
--- src/lib/strex.c
+++ src/lib/strex.c
@@ -58,30 +58,31 @@
     strexBuiltInUncsv,
     strexBuiltInUntsv,
     strexBuiltInReplace,
     strexBuiltInFix,
     strexBuiltInStrip,
     strexBuiltInLen,
     strexBuiltInSymbol,
     strexBuiltInLower,
     strexBuiltInUpper,
     strexBuiltInIn, 
     strexBuiltInStarts,
     strexBuiltInEnds,
     strexBuiltInSame,
     strexBuiltInTidy,
     strexBuiltInWarn,
+    strexBuiltInError,
     };
 
 struct strexBuiltIn
 /* Information to describe a built in function */
     {
     char *name;		/* Name in strex language:  trim, split, etc */
     enum strexBuiltInFunc func;  /* enum version: strexBuiltInTrim strexBuiltInSplit etc. */
     enum strexType returnType;	 /* Type of return value */
     int paramCount;	/* Number of parameters, not flexible in this language! */
     enum strexType *paramTypes;  /* Array of types, one for each parameter */
     };
 
 union strexVal
 /* Some value of arbirary type that can be of any type corresponding to strexType */
     {
@@ -178,30 +179,31 @@
     { "uncsv", strexBuiltInUncsv, strexTypeString, 2, stringInt },
     { "untsv", strexBuiltInUntsv, strexTypeString, 2, stringInt },
     { "replace", strexBuiltInReplace, strexTypeString, 3, threeStrings },
     { "fix", strexBuiltInFix, strexTypeString, 3, threeStrings },
     { "strip", strexBuiltInStrip, strexTypeString, 2, twoStrings },
     { "len", strexBuiltInLen, strexTypeInt, 1, oneString},
     { "symbol", strexBuiltInSymbol, strexTypeString, 2, twoStrings },
     { "upper", strexBuiltInUpper, strexTypeString, 1, oneString },
     { "lower", strexBuiltInLower, strexTypeString, 1, oneString },
     { "in", strexBuiltInIn, strexTypeBoolean, 2, twoStrings },
     { "starts", strexBuiltInStarts, strexTypeBoolean, 2, twoStrings}, 
     { "ends", strexBuiltInEnds, strexTypeBoolean, 2, twoStrings}, 
     { "same", strexBuiltInSame, strexTypeBoolean, 2, twoStrings}, 
     { "tidy", strexBuiltInTidy, strexTypeString, 3, threeStrings },
     { "warn", strexBuiltInWarn, strexTypeString, 1, oneString},
+    { "error", strexBuiltInError, strexTypeString, 1, oneString},
 };
 
 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(struct lineFile *lf,
     void *symbols, StrexLookup lookup)
 /* Return a new strexIn structure wrapped around lineFile */
@@ -1697,30 +1699,45 @@
 	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);
 	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);
+	if (run->abortHandler != NULL) 
+	    run->abortHandler();
+	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;
 
 /* Get pointer to default expression but don't evaluate it yet */
 struct strexParse *defaultExp = p;
 p = p->next;