/* Initial version of var_set_value(), to be called after create_var(). */ static void var_set_initial_value(Var *v, const char *val) { size_t len; len = strlen(val); Buf_Init(&(v->val), len+1); Buf_AddChars(&(v->val), len, val); }
/*- *----------------------------------------------------------------------- * Str_SYSVSubst -- * Substitute '%' in the pattern with len characters from src. * If the pattern does not contain a '%' prepend len characters * from src. * * Side Effects: * Adds result to buf *----------------------------------------------------------------------- */ void Str_SYSVSubst(Buffer buf, const char *pat, const char *src, size_t len) { const char *m; if ((m = strchr(pat, '%')) != NULL) { /* Copy the prefix. */ Buf_Addi(buf, pat, m); /* Skip the %. */ pat = m + 1; } /* Copy the pattern. */ Buf_AddChars(buf, len, src); /* Append the rest. */ Buf_AddString(buf, pat); }
void Var_SubstVar(Buffer buf, /* To store result */ const char *str, /* The string in which to substitute */ struct LoopVar *l, /* Handle */ const char *val) /* Its value */ { const char *var = l->me->name; var_set_value(l->me, val); for (;;) { const char *start; /* Copy uninteresting stuff */ for (start = str; *str != '\0' && *str != '$'; str++) ; Buf_Addi(buf, start, str); start = str; if (*str++ == '\0') break; str++; /* and escaped dollars */ if (start[1] == '$') { Buf_Addi(buf, start, start+2); continue; } /* Simple variable, if it's not us, copy. */ if (start[1] != '(' && start[1] != '{') { if (start[1] != *var || var[1] != '\0') { Buf_AddChars(buf, 2, start); continue; } } else { const char *p; char paren = start[1]; /* Find the end of the variable specification. */ p = find_pos(paren)(str); /* A variable inside the variable. We don't know how to * expand the external variable at this point, so we * try again with the nested variable. */ if (*p == '$') { Buf_Addi(buf, start, p); str = p; continue; } if (strncmp(var, str, p - str) != 0 || var[p - str] != '\0') { /* Not the variable we want to expand. */ Buf_Addi(buf, start, p); str = p; continue; } if (*p == ':') { bool doFree; /* should val be freed ? */ char *newval; struct Name name; doFree = false; name.s = var; name.e = var + (p-str); /* val won't be freed since !doFree, but * VarModifiers_Apply doesn't know that, * hence the cast. */ newval = VarModifiers_Apply((char *)val, &name, NULL, false, &doFree, &p, paren); Buf_AddString(buf, newval); if (doFree) free(newval); str = p; continue; } else str = p+1; } Buf_AddString(buf, val); } }