1203d7c21e26bd5d57154cc5c0c42780b8b5ca1a chmalee Tue Oct 27 10:11:47 2020 -0700 Fixing bug in mouseOver trackDb setting, if a field to be substituted is a prefix to another field to be substituted, allow user to wrap one/both fields in curly braces like shell in order to protect the substitution diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 0794478..3dc1c91 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -9401,39 +9401,56 @@ return list; } static struct dyString *subMultiField(char *pattern, int fieldCount, char *in[], char *out[]) /* Substitute $in with out values in pattern */ { int i; struct dyString *s = newDyString(256), *d = NULL; dyStringAppend(s, pattern); for (i=0; i<fieldCount; ++i) { if (out[i]==NULL) continue; - // prefix field with $ + // If a field is a prefix or suffix to another field, for example 'chrom' and 'chromStart' + // we don't want to erroneously sub out the 'chrom' in 'chromStart'. Allow the wrapping + // protected fields in ${} to prevent the substitution: char *field = in[i]; - char *spec = needMem(strlen(field) + 2); + int fieldLen = strlen(field); + char *spec = needMem(fieldLen + 2); + char *strictSpec = needMem(fieldLen + 4); *spec = '$'; + *strictSpec = '$'; + strictSpec[1] = '{'; strcpy(spec + 1, field); + strcpy(strictSpec + 2, field); + strictSpec[fieldLen + 2] = '}'; + strictSpec[fieldLen + 3] = '\0'; + if (stringIn(strictSpec, s->string)) + { + d = dyStringSub(s->string, strictSpec, out[i]); + s = d; + } + // the user may have both a ${} enclosed instance and a non-enclosed one! d = dyStringSub(s->string, spec, out[i]); + dyStringFree(&s); freeMem(spec); + freeMem(strictSpec); s = d; d = NULL; } return s; } char *replaceFieldInPattern(char *pattern, int fieldCount, char **fieldNames, char **fieldVals) /* Replace $fieldName in pattern with value. Used in trackDb mouseOver setting */ { struct dyString *ds = subMultiField(pattern, fieldCount, fieldNames, fieldVals); return dyStringCannibalize(&ds); } static struct dyString *subMulti(char *orig, int subCount, char *in[], char *out[])