diff options
| author | Hartmut Brandt <harti@FreeBSD.org> | 2005-03-21 12:07:14 +0000 |
|---|---|---|
| committer | Hartmut Brandt <harti@FreeBSD.org> | 2005-03-21 12:07:14 +0000 |
| commit | 8f712e50348f86b40000e7b6fbe1c848920cc3f2 (patch) | |
| tree | cb9cd461b934d812cb385c7ce2967f1c62d2d08d /usr.bin/make/var.c | |
| parent | b072d122834718a6ba575228fe74f937a6392921 (diff) | |
Notes
Diffstat (limited to 'usr.bin/make/var.c')
| -rw-r--r-- | usr.bin/make/var.c | 233 |
1 files changed, 102 insertions, 131 deletions
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 55aa81e7764f..396836fdbdb4 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -109,7 +109,7 @@ typedef struct VarParser { GNode *ctxt; Boolean err; } VarParser; -static char *VarParse(VarParser *, size_t *, Boolean *); +static char *VarParse(VarParser *, Boolean *); /* * This is a harmless return value for Var_Parse that can be used by Var_Subst @@ -910,44 +910,46 @@ VarExpand(Var *v, VarParser *vp) * Select only those words in value that match the modifier. */ static char * -modifier_M(const char mod[], const char value[], char endc, size_t *consumed) +modifier_M(VarParser *vp, const char value[], char endc) { - const char *cur; - char *patt; - char *ptr; - char *newValue; + char *patt; + char *ptr; + char *newValue; + char modifier; + + modifier = vp->ptr[0]; + vp->ptr++; /* consume 'M' or 'N' */ /* * Compress the \:'s out of the pattern, so allocate enough * room to hold the uncompressed pattern and compress the * pattern into that space. */ - patt = estrdup(mod); + patt = estrdup(vp->ptr); ptr = patt; - for (cur = mod + 1; cur != '\0'; cur++) { - if ((cur[0] == endc) || (cur[0] == ':')) { + while (vp->ptr[0] != '\0') { + if ((vp->ptr[0] == endc) || (vp->ptr[0] == ':')) { break; } - if ((cur[0] == '\\') && - ((cur[1] == endc) || (cur[1] == ':'))) { - cur++; /* skip over backslash */ + if ((vp->ptr[0] == '\\') && + ((vp->ptr[1] == endc) || (vp->ptr[1] == ':'))) { + vp->ptr++; /* skip over backslash */ } - *ptr = *cur; + *ptr = vp->ptr[0]; ptr++; + vp->ptr++; } *ptr = '\0'; - if (*mod == 'M' || *mod == 'm') { + if (modifier == 'M') { newValue = VarModify(value, VarMatch, patt); } else { newValue = VarModify(value, VarNoMatch, patt); } free(patt); - *consumed += (cur - mod); - - if (*cur == ':') { - *consumed += 1; /* include colon as part of modifier */ + if (vp->ptr[0] == ':') { + vp->ptr++; /* include colon as part of modifier */ } return (newValue); @@ -958,8 +960,9 @@ modifier_M(const char mod[], const char value[], char endc, size_t *consumed) * is applied to each word in value. */ static char * -modifier_S(const char mod[], const char value[], Var *v, VarParser *vp, size_t *consumed) +modifier_S(VarParser *vp, const char value[], Var *v) { + const char *mod = vp->ptr; VarPattern pattern; Buffer *buf; /* Buffer for patterns */ char delim; @@ -1109,6 +1112,12 @@ modifier_S(const char mod[], const char value[], Var *v, VarParser *vp, size_t * cur++; } + 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 @@ -1127,18 +1136,13 @@ modifier_S(const char mod[], const char value[], Var *v, VarParser *vp, size_t * free(pattern.lhs); free(pattern.rhs); - *consumed += (cur - mod); - - if (cur[0] == ':') { - *consumed += 1; /* include colin as part of modifier */ - } - return (newValue); } static char * -modifier_C(const char mod[], char value[], Var *v, VarParser *vp, size_t *consumed) +modifier_C(VarParser *vp, char value[], Var *v) { + const char *mod = vp->ptr; VarREPattern patt; char delim; char *re; @@ -1178,9 +1182,14 @@ modifier_C(const char mod[], char value[], Var *v, VarParser *vp, size_t *consum break; } + vp->ptr += (cur - mod); + + if (cur[0] == ':') { + vp->ptr++; /* include colin as part of modifier */ + } + error = regcomp(&patt.re, re, REG_EXTENDED); if (error) { - *consumed = cur - mod; VarREError(error, &patt.re, "RE substitution error"); free(patt.replace); free(re); @@ -1201,11 +1210,6 @@ modifier_C(const char mod[], char value[], Var *v, VarParser *vp, size_t *consum free(patt.replace); free(re); - *consumed += (cur - mod); - - if (cur[0] == ':') { - *consumed += 1; /* include colin as part of modifier */ - } return (newValue); } @@ -1235,38 +1239,35 @@ modifier_C(const char mod[], char value[], Var *v, VarParser *vp, size_t *consum * XXXHB update this comment or remove it and point to the man page. */ static char * -ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, size_t *lengthPtr, Boolean *freePtr) +ParseModifier(VarParser *vp, char startc, Boolean dynamic, Var *v, Boolean *freePtr) { - const char *tstr = vp->ptr; - char *value; - size_t used; + char *value; + char endc; value = VarExpand(v, vp); *freePtr = TRUE; - tstr++; - while (*tstr != endc) { + endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE; + + vp->ptr++; + while (*vp->ptr != endc) { char *newStr; /* New value to return */ - size_t consumed = 0; - DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, value)); - switch (*tstr) { + DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *vp->ptr, value)); + switch (*vp->ptr) { case 'N': case 'M': - newStr = modifier_M(tstr, value, endc, &consumed); - tstr += consumed; + newStr = modifier_M(vp, value, endc); break; case 'S': - newStr = modifier_S(tstr, value, v, vp, &consumed); - tstr += consumed; + newStr = modifier_S(vp, value, v); break; case 'C': - newStr = modifier_C(tstr, value, v, vp, &consumed); - tstr += consumed; + newStr = modifier_C(vp, value, v); break; default: - if (tstr[1] == endc || tstr[1] == ':') { - switch (tstr[0]) { + if (vp->ptr[1] == endc || vp->ptr[1] == ':') { + switch (vp->ptr[0]) { case 'L': { const char *cp; @@ -1278,20 +1279,20 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si newStr = (char *)Buf_GetAll(buf, (size_t *)NULL); Buf_Destroy(buf, FALSE); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; } case 'O': newStr = VarSortWords(value, SortIncreasing); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; case 'Q': newStr = Var_Quote(value); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; case 'T': newStr = VarModify(value, VarTail, (void *)NULL); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; case 'U': { @@ -1304,20 +1305,20 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si newStr = (char *)Buf_GetAll(buf, (size_t *)NULL); Buf_Destroy(buf, FALSE); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; } case 'H': newStr = VarModify(value, VarHead, (void *)NULL); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; case 'E': newStr = VarModify(value, VarSuffix, (void *)NULL); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; case 'R': newStr = VarModify(value, VarRoot, (void *)NULL); - tstr += (tstr[1] == ':') ? 2 : 1; + vp->ptr += (vp->ptr[1] == ':') ? 2 : 1; break; default: { @@ -1339,7 +1340,7 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si * translation: it must be: * <string1>=<string2>) */ - cp = tstr; + cp = vp->ptr; cnt = 1; while (*cp != '\0' && cnt) { if (*cp == '=') { @@ -1358,28 +1359,18 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si * lhs and rhs. We must null * terminate them of course. */ - cp = tstr; + cp = vp->ptr; patt.lhs = VarGetPattern(vp, &cp, '=', &patt.flags, &patt.leftLen, NULL); if (patt.lhs == NULL) { - *lengthPtr = cp - vp->input + 1; - if (*freePtr) - free(value); - if ('=' != '\0') - Fatal("Unclosed substitution for %s (%c missing)", - v->name, '='); - return (var_Error); + Fatal("Unclosed substitution for %s (%c missing)", + v->name, '='); } patt.rhs = VarGetPattern(vp, &cp, endc, NULL, &patt.rightLen, &patt); if (patt.rhs == NULL) { - *lengthPtr = cp - vp->input + 1; - if (*freePtr) - free(value); - if (endc != '\0') - Fatal("Unclosed substitution for %s (%c missing)", - v->name, endc); - return (var_Error); + Fatal("Unclosed substitution for %s (%c missing)", + v->name, endc); } /* * SYSV modifications happen through @@ -1392,17 +1383,17 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si free(patt.lhs); free(patt.rhs); - tstr = (endc == ':') ? (cp + 1) : cp; + vp->ptr = (endc == ':') ? (cp + 1) : cp; } else #endif { - Error("Unknown modifier '%c'\n", *tstr); - for (cp = tstr + 1; *cp != '\0'; cp++) { + Error("Unknown modifier '%c'\n", *vp->ptr); + for (cp = vp->ptr + 1; *cp != '\0'; cp++) { if (*cp == ':' && *cp == endc) { break; } } - tstr = (*cp == ':') ? (cp + 1) : cp; + vp->ptr = (*cp == ':') ? (cp + 1) : cp; newStr = var_Error; } } @@ -1411,9 +1402,9 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si } else { #ifdef SUNSHCMD - if ((tstr[0] == 's') && - (tstr[1] == 'h') && - (tstr[2] == endc || tstr[2] == ':')) { + if ((vp->ptr[0] == 's') && + (vp->ptr[1] == 'h') && + (vp->ptr[2] == endc || vp->ptr[2] == ':')) { const char *error; Buffer *buf; @@ -1423,7 +1414,7 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si if (error) Error(error, value); - tstr = (tstr[2] == ':') ? (tstr + 2 + 1) : tstr + 2; + vp->ptr = (vp->ptr[2] == ':') ? (vp->ptr + 2 + 1) : vp->ptr + 2; } else #endif { @@ -1445,7 +1436,7 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si * translation: it must be: * <string1>=<string2>) */ - cp = tstr; + cp = vp->ptr; cnt = 1; while (*cp != '\0' && cnt) { if (*cp == '=') { @@ -1464,28 +1455,18 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si * lhs and rhs. We must null * terminate them of course. */ - cp = tstr; + cp = vp->ptr; patt.lhs = VarGetPattern(vp, &cp, '=', &patt.flags, &patt.leftLen, NULL); if (patt.lhs == NULL) { - *lengthPtr = cp - vp->input + 1; - if (*freePtr) - free(value); - if ('=' != '\0') - Fatal("Unclosed substitution for %s (%c missing)", - v->name, '='); - return (var_Error); + Fatal("Unclosed substitution for %s (%c missing)", + v->name, '='); } patt.rhs = VarGetPattern(vp, &cp, endc, NULL, &patt.rightLen, &patt); if (patt.rhs == NULL) { - *lengthPtr = cp - vp->input + 1; - if (*freePtr) - free(value); - if (endc != '\0') - Fatal("Unclosed substitution for %s (%c missing)", - v->name, endc); - return (var_Error); + Fatal("Unclosed substitution for %s (%c missing)", + v->name, endc); } /* * SYSV modifications happen through @@ -1498,18 +1479,18 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si free(patt.lhs); free(patt.rhs); - tstr = (endc == ':') ? (cp + 1) : cp; + vp->ptr = (endc == ':') ? (cp + 1) : cp; } else #endif { - Error("Unknown modifier '%c'\n", *tstr); - for (cp = tstr + 1; *cp != '\0'; cp++) { + Error("Unknown modifier '%c'\n", *vp->ptr); + for (cp = vp->ptr + 1; *cp != '\0'; cp++) { if (*cp == ':' || *cp == endc) { break; } } newStr = var_Error; - tstr = (*cp == ':') ? (cp + 1) : cp; + vp->ptr = (*cp == ':') ? (cp + 1) : cp; } } @@ -1530,9 +1511,6 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si } } - used = tstr - vp->input + 1; - *lengthPtr = used; - if (v->flags & VAR_FROM_ENV) { if (value == (char *)Buf_GetAll(v->val, (size_t *)NULL)) { VarDestroy(v, FALSE); @@ -1552,11 +1530,12 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si } if (dynamic) { char *result; + size_t consumed = vp->ptr - vp->input + 1; VarDestroy(v, TRUE); - result = emalloc(used + 1); - strncpy(result, vp->input, used); - result[used] = '\0'; + result = emalloc(consumed + 1); + strncpy(result, vp->input, consumed); + result[consumed] = '\0'; *freePtr = TRUE; return (result); @@ -1572,7 +1551,7 @@ ParseModifier(VarParser *vp, char startc, char endc, Boolean dynamic, Var *v, si } static char * -ParseRestModifier(VarParser *vp, char startc, char endc, Buffer *buf, size_t *lengthPtr, Boolean *freePtr) +ParseRestModifier(VarParser *vp, char startc, Buffer *buf, Boolean *freePtr) { const char *vname; size_t vlen; @@ -1588,7 +1567,7 @@ ParseRestModifier(VarParser *vp, char startc, char endc, Buffer *buf, size_t *le v = VarFind(vname, vp->ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); if (v != NULL) { - return (ParseModifier(vp, startc, endc, dynamic, v, lengthPtr, freePtr)); + return (ParseModifier(vp, startc, dynamic, v, freePtr)); } if ((vp->ctxt == VAR_CMD) || (vp->ctxt == VAR_GLOBAL)) { @@ -1624,7 +1603,7 @@ ParseRestModifier(VarParser *vp, char startc, char endc, Buffer *buf, size_t *le * the modifications */ v = VarCreate(vname, NULL, VAR_JUNK); - return (ParseModifier(vp, startc, endc, dynamic, v, lengthPtr, freePtr)); + return (ParseModifier(vp, startc, dynamic, v, freePtr)); } else { /* * Check for D and F forms of local variables since we're in @@ -1643,7 +1622,7 @@ ParseRestModifier(VarParser *vp, char startc, char endc, Buffer *buf, size_t *le v = VarFind(name, vp->ctxt, 0); if (v != NULL) { - return (ParseModifier(vp, startc, endc, dynamic, v, lengthPtr, freePtr)); + return (ParseModifier(vp, startc, dynamic, v, freePtr)); } } @@ -1653,7 +1632,7 @@ ParseRestModifier(VarParser *vp, char startc, char endc, Buffer *buf, size_t *le * the modifications */ v = VarCreate(vname, NULL, VAR_JUNK); - return (ParseModifier(vp, startc, endc, dynamic, v, lengthPtr, freePtr)); + return (ParseModifier(vp, startc, dynamic, v, freePtr)); } } @@ -1765,7 +1744,7 @@ ParseRestEnd(VarParser *vp, Buffer *buf, Boolean *freePtr) * Parse a multi letter variable name, and return it's value. */ static char * -VarParseLong(VarParser *vp, size_t *consumed, Boolean *freePtr) +VarParseLong(VarParser *vp, Boolean *freePtr) { Buffer *buf; char startc; @@ -1779,22 +1758,20 @@ VarParseLong(VarParser *vp, size_t *consumed, Boolean *freePtr) * colon, replacing embedded variables as we go. */ startc = vp->ptr[0]; - endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE; + vp->ptr++; /* consume opening paren or brace */ - vp->ptr += 1; /* consume opening paren or brace */ + endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE; while (*vp->ptr != '\0') { if (*vp->ptr == endc) { vp->ptr++; /* consume closing paren or brace */ result = ParseRestEnd(vp, buf, freePtr); Buf_Destroy(buf, TRUE); - *consumed = vp->ptr - vp->input; return (result); } else if (*vp->ptr == ':') { - *consumed += 1; /* consume '$' */ - *consumed += 1; /* consume paren or brace */ - result = ParseRestModifier(vp, startc, endc, buf, consumed, freePtr); + result = ParseRestModifier(vp, startc, buf, freePtr); + vp->ptr++; /* consume closing paren or brace */ Buf_Destroy(buf, TRUE); return (result); @@ -1811,12 +1788,10 @@ VarParseLong(VarParser *vp, size_t *consumed, Boolean *freePtr) Buf_Append(buf, rval); if (rfree) free(rval); - *consumed += rlen; vp->ptr += rlen; } else { Buf_AddByte(buf, (Byte)*vp->ptr); - *consumed += 1; vp->ptr++; } } @@ -1829,7 +1804,6 @@ VarParseLong(VarParser *vp, size_t *consumed, Boolean *freePtr) */ Buf_Destroy(buf, TRUE); *freePtr = FALSE; - *consumed = vp->ptr - vp->input; return (var_Error); } @@ -1898,9 +1872,8 @@ VarParseShort(VarParser *vp, Boolean *freeResult) } static char * -VarParse(VarParser *vp, size_t *consumed, Boolean *freeResult) +VarParse(VarParser *vp, Boolean *freeResult) { - char *value; /* assert(vp->ptr[0] == '$'); */ @@ -1909,19 +1882,16 @@ VarParse(VarParser *vp, size_t *consumed, Boolean *freeResult) if (vp->ptr[0] == '\0') { /* Error, there is only a dollar sign in the input string. */ *freeResult = FALSE; - value = vp->err ? var_Error : varNoError; - *consumed += vp->ptr - vp->input; + return (vp->err ? var_Error : varNoError); } else if (vp->ptr[0] == OPEN_PAREN || vp->ptr[0] == OPEN_BRACE) { /* multi letter variable name */ - value = VarParseLong(vp, consumed, freeResult); + return (VarParseLong(vp, freeResult)); } else { /* single letter variable name */ - value = VarParseShort(vp, freeResult); - *consumed += vp->ptr - vp->input; + return (VarParseShort(vp, freeResult)); } - return (value); } /*- @@ -1960,7 +1930,8 @@ Var_Parse(const char input[], GNode *ctxt, Boolean err, }; char *value; - value = VarParse(&vp, consumed, freeResult); + value = VarParse(&vp, freeResult); + *consumed += vp.ptr - vp.input; return (value); } |
