From fd4b24126344142f5cffda75c8ece46efb77069c Mon Sep 17 00:00:00 2001 From: Max Okumoto Date: Fri, 4 Mar 2005 23:48:53 +0000 Subject: [PATCH] patch-7.105 ParseModifier() and modifier_S() - move 'S' modifier code into its own function. --- usr.bin/make/var.c | 223 ++++++++++++++++++++++++--------------------- 1 file changed, 121 insertions(+), 102 deletions(-) diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 5120aedc8c..daf16bc655 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -37,7 +37,7 @@ * * @(#)var.c 8.3 (Berkeley) 3/19/94 * $FreeBSD: src/usr.bin/make/var.c,v 1.83 2005/02/11 10:49:01 harti Exp $ - * $DragonFly: src/usr.bin/make/var.c,v 1.128 2005/03/04 23:48:35 okumoto Exp $ + * $DragonFly: src/usr.bin/make/var.c,v 1.129 2005/03/04 23:48:53 okumoto Exp $ */ /*- @@ -962,67 +962,14 @@ modifier_M(const char mod[], const char value[], char endc, size_t *consumed) return (newValue); } - -/* - * Now we need to apply any modifiers the user wants applied. - * These are: - * :M - * words which match the given . - * is of the standard file - * wildcarding form. - * :S[g] - * Substitute for in the value - * :C[g] - * Substitute for regex in the value - * :H Substitute the head of each word - * :T Substitute the tail of each word - * :E Substitute the extension (minus '.') of - * each word - * :R Substitute the root of each word - * (pathname minus the suffix). - * :lhs=rhs - * Like :S, but the rhs goes to the end of - * the invocation. - * :U Converts variable to upper-case. - * :L Converts variable to lower-case. - * - * XXXHB update this comment or remove it and point to the man page. - */ static char * -ParseModifier(const char input[], char tstr[], - char startc, char endc, Boolean dynamic, Var *v, - GNode *ctxt, Boolean err, size_t *lengthPtr, Boolean *freePtr) -{ - char *rw_str; - char *cp; - - rw_str = VarExpand(v, ctxt, err); - *freePtr = TRUE; - - tstr++; - while (*tstr != endc) { - char *newStr; /* New value to return */ - char termc; /* Character which terminated scan */ - Boolean readonly = FALSE; - - DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, rw_str)); - switch (*tstr) { - case 'N': - case 'M': - { - size_t consumed = 0; - - readonly = TRUE; /* tstr isn't modified here */ - - newStr = modifier_M(tstr, rw_str, endc, &consumed); - tstr += consumed; - break; - } - case 'S': +modifier_S(char tstr[], char *rw_str, Var *v, GNode *ctxt, Boolean err, size_t *consumed) { - VarPattern pattern; - char delim; - Buffer *buf; /* Buffer for patterns */ + VarPattern pattern; + Buffer *buf; /* Buffer for patterns */ + char delim; + char *cur; + char *newStr; pattern.flags = 0; buf = Buf_Init(0); @@ -1035,9 +982,10 @@ ParseModifier(const char input[], char tstr[], */ if (tstr[2] == '^') { pattern.flags |= VAR_MATCH_START; - tstr += 1; + cur = tstr + 3; + } else { + cur = tstr + 2; } - tstr += 2; /* * Pass through the lhs looking for 1) escaped delimiters, '$'s and @@ -1045,28 +993,30 @@ ParseModifier(const char input[], char tstr[], * unescaped $'s that aren't before the delimiter (expand the * variable substitution). The result is left in the Buffer buf. */ - for (cp = tstr; cp[0] != delim; cp++) { - if (cp[0] == '\0') { + while (cur[0] != delim) { + if (cur[0] == '\0') { /* * LHS didn't end with the delim, complain and exit. */ Fatal("Unclosed substitution for %s (%c missing)", v->name, delim); - } else if ((cp[0] == '\\') && - ((cp[1] == delim) || - (cp[1] == '$') || - (cp[1] == '\\'))) { - cp++; /* skip backslash */ - Buf_AddByte(buf, (Byte) cp[0]); + } else if ((cur[0] == '\\') && + ((cur[1] == delim) || + (cur[1] == '$') || + (cur[1] == '\\'))) { + cur++; /* skip backslash */ + Buf_AddByte(buf, (Byte) cur[0]); + cur++; - } else if (cp[0] == '$') { - if (cp[1] == delim) { + } else if (cur[0] == '$') { + if (cur[1] == delim) { /* * Unescaped $ at end of pattern => anchor * pattern at end. */ pattern.flags |= VAR_MATCH_END; + cur++; } else { /* * If unescaped dollar sign not before the @@ -1078,19 +1028,19 @@ ParseModifier(const char input[], char tstr[], Boolean freeIt; len = 0; - cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt); - cp += len; + cp2 = Var_Parse(cur, ctxt, err, &len, &freeIt); + cur += len; Buf_Append(buf, cp2); if (freeIt) { free(cp2); } - cp -= 1; } } else { - Buf_AddByte(buf, (Byte)cp[0]); + Buf_AddByte(buf, (Byte)cur[0]); + cur++; } } - tstr = cp + 1; + cur++; /* skip over delim */ /* * Fetch pattern and destroy buffer, but preserve the data in it, @@ -1108,47 +1058,49 @@ ParseModifier(const char input[], char tstr[], */ buf = Buf_Init(0); - for (cp = tstr; cp[0] != delim; cp++) { - if (cp[0] == '\0') { + while (cur[0] != delim) { + if (cur[0] == '\0') { /* * Didn't end with delim character, complain */ Fatal("Unclosed substitution for %s (%c missing)", v->name, delim); - } else if ((cp[0] == '\\') && - ((cp[1] == delim) || - (cp[1] == '&') || - (cp[1] == '\\') || - (cp[1] == '$'))) { - cp++; /* skip backslash */ - Buf_AddByte(buf, (Byte) cp[0]); - - } else if (cp[0] == '$') { - if (cp[1] == delim) { - Buf_AddByte(buf, (Byte) cp[0]); + } else if ((cur[0] == '\\') && + ((cur[1] == delim) || + (cur[1] == '&') || + (cur[1] == '\\') || + (cur[1] == '$'))) { + cur++; /* skip backslash */ + Buf_AddByte(buf, (Byte) cur[0]); + cur++; + + } else if (cur[0] == '$') { + if (cur[1] == delim) { + Buf_AddByte(buf, (Byte) cur[0]); + cur++; } else { char *cp2; size_t len; Boolean freeIt; len = 0; - cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt); - cp += len; + cp2 = Var_Parse(cur, ctxt, err, &len, &freeIt); + cur += len; Buf_Append(buf, cp2); if (freeIt) { free(cp2); } - cp -= 1; } - } else if (cp[0] == '&') { - Buf_AddBytes(buf, pattern.leftLen, - (Byte *) pattern.lhs); + } else if (cur[0] == '&') { + Buf_AddBytes(buf, pattern.leftLen, (Byte *)pattern.lhs); + cur++; } else { - Buf_AddByte(buf, (Byte) cp[0]); + Buf_AddByte(buf, (Byte) cur[0]); + cur++; } } - cp++; + cur++; /* skip over delim */ pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen); Buf_Destroy(buf, FALSE); @@ -1157,9 +1109,9 @@ ParseModifier(const char input[], char tstr[], * Check for global substitution. If 'g' after the final delimiter, * substitution is global and is marked that way. */ - if (cp[0] == 'g') { + if (cur[0] == 'g') { pattern.flags |= VAR_SUB_GLOBAL; - cp++; + cur++; } /* @@ -1172,15 +1124,82 @@ ParseModifier(const char input[], char tstr[], if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL) Fatal("Global substitution of the empty string"); - termc = cp[0]; newStr = VarModify(rw_str, VarSubstitute, &pattern); + /* * Free the two strings. */ free(pattern.lhs); free(pattern.rhs); - break; + + *consumed += (cur - tstr); + + if (cur[0] == ':') { + *consumed += 1; /* include colin as part of modifier */ + } + + return (newStr); } + +/* + * Now we need to apply any modifiers the user wants applied. + * These are: + * :M + * words which match the given . + * is of the standard file + * wildcarding form. + * :S[g] + * Substitute for in the value + * :C[g] + * Substitute for regex in the value + * :H Substitute the head of each word + * :T Substitute the tail of each word + * :E Substitute the extension (minus '.') of + * each word + * :R Substitute the root of each word + * (pathname minus the suffix). + * :lhs=rhs + * Like :S, but the rhs goes to the end of + * the invocation. + * :U Converts variable to upper-case. + * :L Converts variable to lower-case. + * + * XXXHB update this comment or remove it and point to the man page. + */ +static char * +ParseModifier(const char input[], char tstr[], + char startc, char endc, Boolean dynamic, Var *v, + GNode *ctxt, Boolean err, size_t *lengthPtr, Boolean *freePtr) +{ + char *rw_str; + char *cp; + + rw_str = VarExpand(v, ctxt, err); + *freePtr = TRUE; + + tstr++; + while (*tstr != endc) { + char *newStr; /* New value to return */ + char termc; /* Character which terminated scan */ + Boolean readonly = FALSE; + size_t consumed = 0; + + DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, rw_str)); + switch (*tstr) { + case 'N': + case 'M': + readonly = TRUE; /* tstr isn't modified here */ + + newStr = modifier_M(tstr, rw_str, endc, &consumed); + tstr += consumed; + break; + case 'S': + + readonly = TRUE; /* tstr isn't modified here */ + + newStr = modifier_S(tstr, rw_str, v, ctxt, err, &consumed); + tstr += consumed; + break; case 'C': { int delim; -- 2.41.0