diff options
author | harti <harti@FreeBSD.org> | 2005-03-21 12:27:53 +0000 |
---|---|---|
committer | harti <harti@FreeBSD.org> | 2005-03-21 12:27:53 +0000 |
commit | 86fccdb68ec52ebbae1bdfbd39c919931f276b0b (patch) | |
tree | c07b6bb84d2eaf4c10db9586e0839c95be7a1996 /usr.bin/make/var.c | |
parent | ae5d59a29a844bb2def5ef66d7d2df92653bbdb4 (diff) | |
download | FreeBSD-src-86fccdb68ec52ebbae1bdfbd39c919931f276b0b.zip FreeBSD-src-86fccdb68ec52ebbae1bdfbd39c919931f276b0b.tar.gz |
Split out SysV variable substitution into its own function.
Patch: 7.139
Submitted by: Max Okumoto <okumoto@ucsd.edu>
Diffstat (limited to 'usr.bin/make/var.c')
-rw-r--r-- | usr.bin/make/var.c | 379 |
1 files changed, 151 insertions, 228 deletions
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 178e597..a71ca94 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -948,10 +948,6 @@ modifier_M(VarParser *vp, const char value[], char endc) } free(patt); - if (vp->ptr[0] == ':') { - vp->ptr++; /* include colon as part of modifier */ - } - return (newValue); } @@ -1114,10 +1110,6 @@ modifier_S(VarParser *vp, const char value[], Var *v) vp->ptr += (cur - mod); - if (cur[0] == ':') { - vp->ptr++; /* include colin as part of modifier */ - } - /* * Global substitution of the empty string causes an infinite number * of matches, unless anchored by '^' (start of string) or '$' (end @@ -1184,10 +1176,6 @@ modifier_C(VarParser *vp, char value[], Var *v) vp->ptr += (cur - mod); - if (cur[0] == ':') { - vp->ptr++; /* include colin as part of modifier */ - } - error = regcomp(&patt.re, re, REG_EXTENDED); if (error) { VarREError(error, &patt.re, "RE substitution error"); @@ -1213,6 +1201,87 @@ modifier_C(VarParser *vp, char value[], Var *v) return (newValue); } +static char * +sysVvarsub(VarParser *vp, char startc, Var *v, const char value[]) +{ +#ifdef SYSVVARSUB + /* + * This can either be a bogus modifier or a System-V substitution + * command. + */ + char endc; + VarPattern patt; + Boolean eqFound; + int cnt; + char *newStr; + const char *cp; + + endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE; + + patt.flags = 0; + + /* + * First we make a pass through the string trying to verify it is a + * SYSV-make-style translation: it must be: <string1>=<string2>) + */ + cp = vp->ptr; + cnt = 1; + eqFound = FALSE; + while (*cp != '\0' && cnt) { + if (*cp == '=') { + eqFound = TRUE; + /* continue looking for endc */ + } else if (*cp == endc) + cnt--; + else if (*cp == startc) + cnt++; + if (cnt) + cp++; + } + + if (*cp == endc && eqFound) { + /* + * Now we break this sucker into the lhs and rhs. + */ + cp = vp->ptr; + + patt.lhs = VarGetPattern(vp, &cp, '=', &patt.flags, &patt.leftLen, NULL); + if (patt.lhs == NULL) { + Fatal("Unclosed substitution for %s (%c missing)", + v->name, '='); + } + patt.rhs = VarGetPattern(vp, &cp, endc, NULL, &patt.rightLen, &patt); + if (patt.rhs == NULL) { + Fatal("Unclosed substitution for %s (%c missing)", + v->name, endc); + } + vp->ptr = cp - 1; /* put pointer on top of endc */ + + /* + * SYSV modifications happen through the whole string. Note + * the pattern is anchored at the end. + */ + newStr = VarModify(value, VarSYSVMatch, &patt); + + free(patt.lhs); + free(patt.rhs); + } else +#endif + { + Error("Unknown modifier '%c'\n", *vp->ptr); + vp->ptr++; + while (*vp->ptr != '\0') { + if (*vp->ptr == endc && *vp->ptr == ':') { + break; + } + vp->ptr++; + } + newStr = var_Error; + } + + return (newStr); +} + /* * Now we need to apply any modifiers the user wants applied. * These are: @@ -1249,10 +1318,15 @@ ParseModifier(VarParser *vp, char startc, Var *v, Boolean *freeResult) endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE; - vp->ptr++; - while (*vp->ptr != endc) { + vp->ptr++; /* consume first colon */ + + while (*vp->ptr != '\0') { char *newStr; /* New value to return */ + if (*vp->ptr == endc) { + return (value); + } + DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *vp->ptr, value)); switch (*vp->ptr) { case 'N': @@ -1266,141 +1340,7 @@ ParseModifier(VarParser *vp, char startc, Var *v, Boolean *freeResult) newStr = modifier_C(vp, value, v); break; default: - if (vp->ptr[1] == endc || vp->ptr[1] == ':') { - switch (vp->ptr[0]) { - case 'L': - { - const char *cp; - Buffer *buf; - buf = Buf_Init(MAKE_BSIZE); - for (cp = value; *cp; cp++) - Buf_AddByte(buf, (Byte)tolower(*cp)); - - newStr = (char *)Buf_GetAll(buf, (size_t *)NULL); - Buf_Destroy(buf, FALSE); - - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - } - case 'O': - newStr = VarSortWords(value, SortIncreasing); - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - case 'Q': - newStr = Var_Quote(value); - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - case 'T': - newStr = VarModify(value, VarTail, (void *)NULL); - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - case 'U': - { - const char *cp; - Buffer *buf; - buf = Buf_Init(MAKE_BSIZE); - for (cp = value; *cp; cp++) - Buf_AddByte(buf, (Byte)toupper(*cp)); - - newStr = (char *)Buf_GetAll(buf, (size_t *)NULL); - Buf_Destroy(buf, FALSE); - - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - } - case 'H': - newStr = VarModify(value, VarHead, (void *)NULL); - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - case 'E': - newStr = VarModify(value, VarSuffix, (void *)NULL); - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - case 'R': - newStr = VarModify(value, VarRoot, (void *)NULL); - vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; - break; - default: - { - const char *cp; -#ifdef SYSVVARSUB - /* - * This can either be a bogus modifier or a - * System-V substitution command. - */ - VarPattern patt; - Boolean eqFound; - int cnt; - - patt.flags = 0; - eqFound = FALSE; - /* - * First we make a pass through the string - * trying to verify it is a SYSV-make-style - * translation: it must be: - * <string1>=<string2>) - */ - cp = vp->ptr; - cnt = 1; - while (*cp != '\0' && cnt) { - if (*cp == '=') { - eqFound = TRUE; - /* continue looking for endc */ - } else if (*cp == endc) - cnt--; - else if (*cp == startc) - cnt++; - if (cnt) - cp++; - } - if (*cp == endc && eqFound) { - /* - * Now we break this sucker into the - * lhs and rhs. We must null - * terminate them of course. - */ - cp = vp->ptr; - - patt.lhs = VarGetPattern(vp, &cp, '=', &patt.flags, &patt.leftLen, NULL); - if (patt.lhs == NULL) { - Fatal("Unclosed substitution for %s (%c missing)", - v->name, '='); - } - - patt.rhs = VarGetPattern(vp, &cp, endc, NULL, &patt.rightLen, &patt); - if (patt.rhs == NULL) { - Fatal("Unclosed substitution for %s (%c missing)", - v->name, endc); - } - /* - * SYSV modifications happen through - * the whole string. Note the pattern - * is anchored at the end. - */ - --cp; - newStr = VarModify(value, VarSYSVMatch, &patt); - - free(patt.lhs); - free(patt.rhs); - - vp->ptr = (endc == ':') ? (cp + 1) : cp; - } else -#endif - { - Error("Unknown modifier '%c'\n", *vp->ptr); - for (cp = vp->ptr + 1; *cp != '\0'; cp++) { - if (*cp == ':' && *cp == endc) { - break; - } - } - vp->ptr = (*cp == ':') ? (cp + 1) : cp; - newStr = var_Error; - } - } - break; - } - - } else { + if (vp->ptr[1] != endc && vp->ptr[1] != ':') { #ifdef SUNSHCMD if ((vp->ptr[0] == 's') && (vp->ptr[1] == 'h') && @@ -1414,87 +1354,71 @@ ParseModifier(VarParser *vp, char startc, Var *v, Boolean *freeResult) if (error) Error(error, value); - vp->ptr = (vp->ptr[2] == ':') ? (vp->ptr + 2 + 1) : vp->ptr + 2; + vp->ptr += 2; } else #endif { - const char *cp; -#ifdef SYSVVARSUB - /* - * This can either be a bogus modifier or a - * System-V substitution command. - */ - VarPattern patt; - Boolean eqFound; - int cnt; - - patt.flags = 0; - eqFound = FALSE; - /* - * First we make a pass through the string - * trying to verify it is a SYSV-make-style - * translation: it must be: - * <string1>=<string2>) - */ - cp = vp->ptr; - cnt = 1; - while (*cp != '\0' && cnt) { - if (*cp == '=') { - eqFound = TRUE; - /* continue looking for endc */ - } else if (*cp == endc) - cnt--; - else if (*cp == startc) - cnt++; - if (cnt) - cp++; - } - if (*cp == endc && eqFound) { - /* - * Now we break this sucker into the - * lhs and rhs. We must null - * terminate them of course. - */ - cp = vp->ptr; + newStr = sysVvarsub(vp, startc, v, value); + } + break; + } - patt.lhs = VarGetPattern(vp, &cp, '=', &patt.flags, &patt.leftLen, NULL); - if (patt.lhs == NULL) { - Fatal("Unclosed substitution for %s (%c missing)", - v->name, '='); - } + switch (vp->ptr[0]) { + case 'L': + { + const char *cp; + Buffer *buf; + buf = Buf_Init(MAKE_BSIZE); + for (cp = value; *cp; cp++) + Buf_AddByte(buf, (Byte)tolower(*cp)); - patt.rhs = VarGetPattern(vp, &cp, endc, NULL, &patt.rightLen, &patt); - if (patt.rhs == NULL) { - Fatal("Unclosed substitution for %s (%c missing)", - v->name, endc); - } - /* - * SYSV modifications happen through - * the whole string. Note the pattern - * is anchored at the end. - */ - --cp; - newStr = VarModify(value, VarSYSVMatch, &patt); + newStr = (char *)Buf_GetAll(buf, NULL); + Buf_Destroy(buf, FALSE); - free(patt.lhs); - free(patt.rhs); + vp->ptr++; + break; + } + case 'O': + newStr = VarSortWords(value, SortIncreasing); + vp->ptr++; + break; + case 'Q': + newStr = Var_Quote(value); + vp->ptr++; + break; + case 'T': + newStr = VarModify(value, VarTail, NULL); + vp->ptr++; + break; + case 'U': + { + const char *cp; + Buffer *buf; + buf = Buf_Init(MAKE_BSIZE); + for (cp = value; *cp; cp++) + Buf_AddByte(buf, (Byte)toupper(*cp)); - vp->ptr = (endc == ':') ? (cp + 1) : cp; - } else -#endif - { - Error("Unknown modifier '%c'\n", *vp->ptr); - for (cp = vp->ptr + 1; *cp != '\0'; cp++) { - if (*cp == ':' || *cp == endc) { - break; - } - } - newStr = var_Error; - vp->ptr = (*cp == ':') ? (cp + 1) : cp; - } + newStr = (char *)Buf_GetAll(buf, NULL); + Buf_Destroy(buf, FALSE); + vp->ptr++; + break; } - + case 'H': + newStr = VarModify(value, VarHead, NULL); + vp->ptr++; + break; + case 'E': + newStr = VarModify(value, VarSuffix, NULL); + vp->ptr++; + break; + case 'R': + newStr = VarModify(value, VarRoot, NULL); + vp->ptr++; + break; + default: + newStr = sysVvarsub(vp, startc, v, value); + break; } break; } @@ -1503,11 +1427,12 @@ ParseModifier(VarParser *vp, char startc, Var *v, Boolean *freeResult) if (*freeResult) { free(value); } + value = newStr; - if (value != var_Error) { - *freeResult = TRUE; - } else { - *freeResult = FALSE; + *freeResult = (value == var_Error) ? FALSE : TRUE; + + if (vp->ptr[0] == ':') { + vp->ptr++; /* consume colon */ } } @@ -1846,9 +1771,7 @@ VarParseShort(VarParser *vp, Boolean *freeResult) } } - /* - * Variable name was not found. - */ + /* Variable name was not found. */ *freeResult = FALSE; return (vp->err ? var_Error : varNoError); } |