2d795fa03e0ef57637885b4ddf9d13832143799b kent Fri Aug 16 11:55:57 2019 -0700 Adding tidy builtin function. diff --git src/lib/strex.c src/lib/strex.c index 41082c6..81c4c37 100644 --- src/lib/strex.c +++ src/lib/strex.c @@ -55,30 +55,31 @@ strexBuiltInMd5, strexBuiltInSeparate, strexBuiltInUncsv, strexBuiltInUntsv, strexBuiltInReplace, strexBuiltInFix, strexBuiltInStrip, strexBuiltInLen, strexBuiltInSymbol, strexBuiltInLower, strexBuiltInUpper, strexBuiltInIn, strexBuiltInStarts, strexBuiltInEnds, strexBuiltInSame, + strexBuiltInTidy, }; 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 */ { @@ -173,30 +174,31 @@ { "md5", strexBuiltInMd5, strexTypeString, 1, oneString }, { "separate", strexBuiltInSeparate, strexTypeString, 3, stringStringInt }, { "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 }, }; static struct hash *hashBuiltIns() /* Build a hash of builtins keyed by name */ { struct hash *hash = hashNew(0); int i; for (i=0; i 32) { char *md5 = hmacMd5("", original); strcpy(result + prefixSize, md5); freeMem(md5); } return result; } static struct strexEval strexEvalCallBuiltIn(struct strexParse *p, void *record, StrexLookup lookup, struct lm *lm) @@ -1602,30 +1611,66 @@ } case strexBuiltInEnds: { struct strexEval string = strexLocalEval(p->children, record, lookup, lm); struct strexEval end = strexLocalEval(p->children->next, record, lookup, lm); res.val.b = endsWith(string.val.s, end.val.s); break; } case strexBuiltInSame: { struct strexEval a = strexLocalEval(p->children, record, lookup, lm); struct strexEval b = strexLocalEval(p->children->next, record, lookup, lm); res.val.b = (strcmp(a.val.s, b.val.s) == 0); break; } + case strexBuiltInTidy: + { + /* Get parameters */ + struct strexEval a = strexLocalEval(p->children, record, lookup, lm); + struct strexEval b = strexLocalEval(p->children->next, record, lookup, lm); + struct strexEval c = strexLocalEval(p->children->next->next, record, lookup, lm); + char *before = a.val.s; + char *orig = b.val.s; + char *after = c.val.s; + + /* Figure out start position - start of string if before string is empty or doesn't match + * otherwise right after the place where before matches. */ + char *ourStart = NULL; + if (!isEmpty(before)) + { + ourStart = strstr(orig, before); + if (ourStart != NULL) + ourStart += strlen(before); + } + if (ourStart == NULL) + ourStart = orig; + + /* Figure out end position */ + char *defaultEnd = ourStart + strlen(ourStart); + char *ourEnd = NULL; + if (!isEmpty(after)) + { + ourEnd = strstr(ourStart, after); + } + if (ourEnd == NULL) + ourEnd = defaultEnd; + + int size = ourEnd - ourStart; + assert(size >= 0); + res.val.s = lmCloneStringZ(lm, ourStart, size); + } } return res; } static struct strexEval strexEvalPick(struct strexParse *pick, void *record, StrexLookup lookup, struct lm *lm) /* Evaluate a pick operator. */ { /* Evaluate the keyValue */ struct strexParse *p = pick->children; struct strexEval keyVal = strexLocalEval(p, record, lookup, lm); p = p->next; /* Get pointer to default expression but don't evaluate it yet */ struct strexParse *defaultExp = p;