=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/varmodifiers.c,v retrieving revision 1.48 retrieving revision 1.49 diff -c -r1.48 -r1.49 *** src/usr.bin/make/varmodifiers.c 2020/08/30 12:16:04 1.48 --- src/usr.bin/make/varmodifiers.c 2023/09/04 11:35:11 1.49 *************** *** 1,4 **** ! /* $OpenBSD: varmodifiers.c,v 1.48 2020/08/30 12:16:04 tb Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* --- 1,4 ---- ! /* $OpenBSD: varmodifiers.c,v 1.49 2023/09/04 11:35:11 espie Exp $ */ /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */ /* *************** *** 65,70 **** --- 65,71 ---- * is also called directly by Var_SubstVar. */ + #include #include #include #include *************** *** 72,78 **** #include #include #include - #include "config.h" #include "defines.h" #include "buf.h" #include "var.h" --- 73,78 ---- *************** *** 100,106 **** #define VAR_BANG_EQUAL 0x100 typedef struct { ! char *lbuffer; /* left string to free */ char *lhs; /* String to match */ size_t leftLen; /* Length of string */ char *rhs; /* Replacement string (w/ &'s removed) */ --- 100,106 ---- #define VAR_BANG_EQUAL 0x100 typedef struct { ! char *lbuffer; /* Left string to free */ char *lhs; /* String to match */ size_t leftLen; /* Length of string */ char *rhs; /* Replacement string (w/ &'s removed) */ *************** *** 108,119 **** int flags; } VarPattern; - struct LoopStuff { - struct LoopVar *var; - char *expand; - bool err; - }; - static bool VarHead(struct Name *, bool, Buffer, void *); static bool VarTail(struct Name *, bool, Buffer, void *); static bool VarSuffix(struct Name *, bool, Buffer, void *); --- 108,113 ---- *************** *** 121,128 **** static bool VarMatch(struct Name *, bool, Buffer, void *); static bool VarSYSVMatch(struct Name *, bool, Buffer, void *); static bool VarNoMatch(struct Name *, bool, Buffer, void *); - static bool VarUniq(struct Name *, bool, Buffer, void *); - static bool VarLoop(struct Name *, bool, Buffer, void *); static void VarREError(int, regex_t *, const char *); --- 115,120 ---- *************** *** 149,210 **** static char *do_lower(const char *, const struct Name *, void *); static void *check_shcmd(const char **, SymTable *, bool, int); static char *do_shcmd(const char *, const struct Name *, void *); - static char *do_sort(const char *, const struct Name *, void *); - static char *finish_loop(const char *, const struct Name *, void *); - static int NameCompare(const void *, const void *); - static char *do_label(const char *, const struct Name *, void *); - static char *do_path(const char *, const struct Name *, void *); - static char *do_def(const char *, const struct Name *, void *); - static char *do_undef(const char *, const struct Name *, void *); - static char *do_assign(const char *, const struct Name *, void *); - static char *do_exec(const char *, const struct Name *, void *); - - static void *assign_get_value(const char **, SymTable *, bool, int); - static void *get_cmd(const char **, SymTable *, bool, int); - static void *get_value(const char **, SymTable *, bool, int); static void *get_stringarg(const char **, SymTable *, bool, int); static void free_stringarg(void *); static void *get_patternarg(const char **, SymTable *, bool, int); static void *get_spatternarg(const char **, SymTable *, bool, int); static void *common_get_patternarg(const char **, SymTable *, bool, int, bool); static void free_patternarg(void *); - static void free_looparg(void *); static void *get_sysvpattern(const char **, SymTable *, bool, int); - static void *get_loop(const char **, SymTable *, bool, int); - static char *LoopGrab(const char **); static struct Name dummy; static struct Name *dummy_arg = &dummy; static struct modifier { - bool atstart; void * (*getarg)(const char **, SymTable *, bool, int); char * (*apply)(const char *, const struct Name *, void *); bool (*word_apply)(struct Name *, bool, Buffer, void *); void (*freearg)(void *); } *choose_mod[256], ! match_mod = {false, get_stringarg, NULL, VarMatch, free_stringarg}, ! nomatch_mod = {false, get_stringarg, NULL, VarNoMatch, free_stringarg}, ! subst_mod = {false, get_spatternarg, NULL, VarSubstitute, free_patternarg}, ! resubst_mod = {false, get_patternarg, do_regex, NULL, free_patternarg}, ! quote_mod = {false, check_quote, VarQuote, NULL , free}, ! tail_mod = {false, check_empty, NULL, VarTail, NULL}, ! head_mod = {false, check_empty, NULL, VarHead, NULL}, ! suffix_mod = {false, check_empty, NULL, VarSuffix, NULL}, ! root_mod = {false, check_empty, NULL, VarRoot, NULL}, ! upper_mod = {false, check_empty, do_upper, NULL, NULL}, ! lower_mod = {false, check_empty, do_lower, NULL, NULL}, ! shcmd_mod = {false, check_shcmd, do_shcmd, NULL, NULL}, ! sysv_mod = {false, get_sysvpattern, NULL, VarSYSVMatch, free_patternarg}, ! uniq_mod = {false, check_empty, NULL, VarUniq, NULL}, ! sort_mod = {false, check_empty, do_sort, NULL, NULL}, ! loop_mod = {false, get_loop, finish_loop, VarLoop, free_looparg}, ! undef_mod = {true, get_value, do_undef, NULL, NULL}, ! def_mod = {true, get_value, do_def, NULL, NULL}, ! label_mod = {true, check_empty, do_label, NULL, NULL}, ! path_mod = {true, check_empty, do_path, NULL, NULL}, ! assign_mod = {true, assign_get_value, do_assign, NULL, free_patternarg}, ! exec_mod = {true, get_cmd, do_exec, NULL, free_patternarg} ; void --- 141,176 ---- static char *do_lower(const char *, const struct Name *, void *); static void *check_shcmd(const char **, SymTable *, bool, int); static char *do_shcmd(const char *, const struct Name *, void *); static void *get_stringarg(const char **, SymTable *, bool, int); static void free_stringarg(void *); static void *get_patternarg(const char **, SymTable *, bool, int); static void *get_spatternarg(const char **, SymTable *, bool, int); static void *common_get_patternarg(const char **, SymTable *, bool, int, bool); static void free_patternarg(void *); static void *get_sysvpattern(const char **, SymTable *, bool, int); static struct Name dummy; static struct Name *dummy_arg = &dummy; static struct modifier { void * (*getarg)(const char **, SymTable *, bool, int); char * (*apply)(const char *, const struct Name *, void *); bool (*word_apply)(struct Name *, bool, Buffer, void *); void (*freearg)(void *); } *choose_mod[256], ! match_mod = {get_stringarg, NULL, VarMatch, free_stringarg}, ! nomatch_mod = {get_stringarg, NULL, VarNoMatch, free_stringarg}, ! subst_mod = {get_spatternarg, NULL, VarSubstitute, free_patternarg}, ! resubst_mod = {get_patternarg, do_regex, NULL, free_patternarg}, ! quote_mod = {check_quote, VarQuote, NULL , free}, ! tail_mod = {check_empty, NULL, VarTail, NULL}, ! head_mod = {check_empty, NULL, VarHead, NULL}, ! suffix_mod = {check_empty, NULL, VarSuffix, NULL}, ! root_mod = {check_empty, NULL, VarRoot, NULL}, ! upper_mod = {check_empty, do_upper, NULL, NULL}, ! lower_mod = {check_empty, do_lower, NULL, NULL}, ! shcmd_mod = {check_shcmd, do_shcmd, NULL, NULL}, ! sysv_mod = {get_sysvpattern, NULL, VarSYSVMatch, free_patternarg} ; void *************** *** 219,245 **** choose_mod['H'] = &head_mod; choose_mod['E'] = &suffix_mod; choose_mod['R'] = &root_mod; ! if (FEATURES(FEATURE_UPPERLOWER)) { ! choose_mod['U'] = &upper_mod; ! choose_mod['L'] = &lower_mod; ! } ! if (FEATURES(FEATURE_SUNSHCMD)) ! choose_mod['s'] = &shcmd_mod; ! if (FEATURES(FEATURE_UNIQ)) ! choose_mod['u'] = &uniq_mod; ! if (FEATURES(FEATURE_SORT)) ! choose_mod['O'] = &sort_mod; ! if (FEATURES(FEATURE_ODE)) { ! choose_mod['@'] = &loop_mod; ! choose_mod['D'] = &def_mod; ! choose_mod['U'] = &undef_mod; ! choose_mod['L'] = &label_mod; ! choose_mod['P'] = &path_mod; ! } ! if (FEATURES(FEATURE_ASSIGN)) ! choose_mod[':'] = &assign_mod; ! if (FEATURES(FEATURE_EXECMOD)) ! choose_mod['!'] = &exec_mod; } /* All modifiers handle addSpace (need to add a space before placing the --- 185,193 ---- choose_mod['H'] = &head_mod; choose_mod['E'] = &suffix_mod; choose_mod['R'] = &root_mod; ! choose_mod['U'] = &upper_mod; ! choose_mod['L'] = &lower_mod; ! choose_mod['s'] = &shcmd_mod; } /* All modifiers handle addSpace (need to add a space before placing the *************** *** 345,352 **** *----------------------------------------------------------------------- */ static bool ! VarMatch(struct Name *word, bool addSpace, Buffer buf, ! void *pattern) /* Pattern the word must match */ { const char *pat = pattern; --- 293,299 ---- *----------------------------------------------------------------------- */ static bool ! VarMatch(struct Name *word, bool addSpace, Buffer buf, void *pattern) { const char *pat = pattern; *************** *** 366,373 **** *----------------------------------------------------------------------- */ static bool ! VarNoMatch(struct Name *word, bool addSpace, Buffer buf, ! void *pattern) /* Pattern the word must not match */ { const char *pat = pattern; --- 313,319 ---- *----------------------------------------------------------------------- */ static bool ! VarNoMatch(struct Name *word, bool addSpace, Buffer buf, void *pattern) { const char *pat = pattern; *************** *** 380,577 **** return addSpace; } - static bool - VarUniq(struct Name *word, bool addSpace, Buffer buf, void *lastp) - { - struct Name *last = lastp; - - /* does not match */ - if (last->s == NULL || last->e - last->s != word->e - word->s || - strncmp(word->s, last->s, word->e - word->s) != 0) { - if (addSpace) - Buf_AddSpace(buf); - Buf_Addi(buf, word->s, word->e); - addSpace = true; - } - last->s = word->s; - last->e = word->e; - return addSpace; - } - - static bool - VarLoop(struct Name *word, bool addSpace, Buffer buf, void *vp) - { - struct LoopStuff *v = vp; - - if (addSpace) - Buf_AddSpace(buf); - Var_SubstVar(buf, v->expand, v->var, word->s); - return true; - } - - static char * - finish_loop(const char *s, const struct Name *n UNUSED , void *p) - { - struct LoopStuff *l = p; - - return Var_Subst(s, NULL, l->err); - } - - static int - NameCompare(const void *ap, const void *bp) - { - const struct Name *a, *b; - size_t n, m; - int c; - - a = ap; - b = bp; - n = a->e - a->s; - m = b->e - b->s; - if (n < m) { - c = strncmp(a->s, b->s, n); - if (c != 0) - return c; - else - return -1; - } else if (m < n) { - c = strncmp(a->s, b->s, m); - if (c != 0) - return c; - else - return 1; - } else - return strncmp(a->s, b->s, n); - } - - static char * - do_sort(const char *s, const struct Name *dummy UNUSED, void *arg UNUSED) - { - struct Name *t; - unsigned long n, i, j; - const char *start, *end; - - n = 1024; /* start at 1024 words */ - t = ereallocarray(NULL, n, sizeof(struct Name)); - start = s; - end = start; - - for (i = 0;; i++) { - if (i == n) { - n *= 2; - t = ereallocarray(t, n, sizeof(struct Name)); - } - start = iterate_words(&end); - if (start == NULL) - break; - t[i].s = start; - t[i].e = end; - } - if (i > 0) { - BUFFER buf; - - Buf_Init(&buf, end - s); - qsort(t, i, sizeof(struct Name), NameCompare); - Buf_Addi(&buf, t[0].s, t[0].e); - for (j = 1; j < i; j++) { - Buf_AddSpace(&buf); - Buf_Addi(&buf, t[j].s, t[j].e); - } - free(t); - return Buf_Retrieve(&buf); - } else { - free(t); - return ""; - } - } - - static char * - do_label(const char *s UNUSED, const struct Name *n, void *arg UNUSED) - { - return Str_dupi(n->s, n->e); - } - - static char * - do_path(const char *s UNUSED, const struct Name *n, void *arg UNUSED) - { - GNode *gn; - - gn = Targ_FindNodei(n->s, n->e, TARG_NOCREATE); - if (gn == NULL) - return Str_dupi(n->s, n->e); - else - return strdup(gn->path); - } - - static char * - do_def(const char *s, const struct Name *n UNUSED, void *arg) - { - VarPattern *v = arg; - if (s == NULL) { - free_patternarg(v); - return NULL; - } else - return v->lbuffer; - } - - static char * - do_undef(const char *s, const struct Name *n UNUSED, void *arg) - { - VarPattern *v = arg; - if (s != NULL) { - free_patternarg(v); - return NULL; - } else - return v->lbuffer; - } - - static char * - do_assign(const char *s, const struct Name *n, void *arg) - { - VarPattern *v = arg; - char *msg; - char *result; - - switch (v->flags) { - case VAR_EQUAL: - Var_Seti(n->s, n->e, v->lbuffer); - break; - case VAR_MAY_EQUAL: - if (s == NULL) - Var_Seti(n->s, n->e, v->lbuffer); - break; - case VAR_ADD_EQUAL: - if (s == NULL) - Var_Seti(n->s, n->e, v->lbuffer); - else - Var_Appendi(n->s, n->e, v->lbuffer); - break; - case VAR_BANG_EQUAL: - result = Cmd_Exec(v->lbuffer, &msg); - if (result != NULL) { - Var_Seti(n->s, n->e, result); - free(result); - } else - Error(msg, v->lbuffer); - break; - - } - return NULL; - } - - static char * - do_exec(const char *s UNUSED, const struct Name *n UNUSED, void *arg) - { - VarPattern *v = arg; - char *msg; - char *result; - - result = Cmd_Exec(v->lbuffer, &msg); - if (result == NULL) - Error(msg, v->lbuffer); - return result; - } - /*- *----------------------------------------------------------------------- * VarSYSVMatch -- --- 326,331 ---- *************** *** 958,964 **** *----------------------------------------------------------------------- * VarModify -- * Modify each of the words of the passed string using the given ! * function. Used to implement all modifiers. * * Results: * A string of all the words modified appropriately. --- 712,718 ---- *----------------------------------------------------------------------- * VarModify -- * Modify each of the words of the passed string using the given ! * function. Used to implement most modifiers. * * Results: * A string of all the words modified appropriately. *************** *** 1218,1274 **** return common_get_patternarg(p, ctxt, err, endc, true); } - static void - free_looparg(void *arg) - { - struct LoopStuff *l = arg; - - Var_DeleteLoopVar(l->var); - free(l->expand); - } - - static char * - LoopGrab(const char **s) - { - const char *p, *start; - - start = *s; - for (p = start; *p != '@'; p++) { - if (*p == '\\') - p++; - if (*p == 0) - return NULL; - } - *s = p+1; - return escape_dupi(start, p, "@\\"); - } - static void * - get_loop(const char **p, SymTable *ctxt UNUSED, bool err, int endc) - { - static struct LoopStuff loop; - const char *s; - const char *var; - - s = *p +1; - - loop.var = NULL; - loop.expand = NULL; - loop.err = err; - var = LoopGrab(&s); - if (var != NULL) { - loop.expand = LoopGrab(&s); - if (*s == endc || *s == ':') { - *p = s; - loop.var = Var_NewLoopVar(var, NULL); - return &loop; - } - } - free_looparg(&loop); - return NULL; - } - - static void * common_get_patternarg(const char **p, SymTable *ctxt, bool err, int endc, bool dosubst) { --- 972,978 ---- *************** *** 1328,1398 **** return NULL; } - static void * - assign_get_value(const char **p, SymTable *ctxt, bool err, int endc) - { - const char *s; - int flags; - VarPattern *arg; - - s = *p + 1; - if (s[0] == '=') - flags = VAR_EQUAL; - else if (s[0] == '?' && s[1] == '=') - flags = VAR_MAY_EQUAL; - else if (s[0] == '+' && s[1] == '=') - flags = VAR_ADD_EQUAL; - else if (s[0] == '!' && s[1] == '=') - flags = VAR_BANG_EQUAL; - else - return NULL; - - arg = get_value(&s, ctxt, err, endc); - if (arg != NULL) { - *p = s; - arg->flags = flags; - } - return arg; - } - - static void * - get_value(const char **p, SymTable *ctxt, bool err, int endc) - { - VarPattern *pattern; - const char *s; - - pattern = emalloc(sizeof(VarPattern)); - s = *p + 1; - pattern->rhs = NULL; - pattern->lbuffer = VarGetPattern(ctxt, err, &s, ':', endc, - &pattern->leftLen, NULL); - if (s[-1] == endc || s[-1] == ':') { - *p = s-1; - return pattern; - } - free_patternarg(pattern); - return NULL; - } - - static void * - get_cmd(const char **p, SymTable *ctxt, bool err, int endc UNUSED) - { - VarPattern *pattern; - const char *s; - - pattern = emalloc(sizeof(VarPattern)); - s = *p + 1; - pattern->rhs = NULL; - pattern->lbuffer = VarGetPattern(ctxt, err, &s, '!', '!', - &pattern->leftLen, NULL); - if (s[-1] == '!') { - *p = s-1; - return pattern; - } - free_patternarg(pattern); - return NULL; - } - static void free_patternarg(void *p) { --- 1032,1037 ---- *************** *** 1435,1441 **** bool err, bool *freePtr, const char **pscan, int paren) { const char *tstr; - bool atstart; /* Some ODE modifiers only make sense at start */ char endc = paren == '(' ? ')' : '}'; const char *start = *pscan; --- 1074,1079 ---- *************** *** 1462,1468 **** * the invocation. */ - atstart = true; while (*tstr != endc && *tstr != '\0') { struct modifier *mod; void *arg; --- 1100,1105 ---- *************** *** 1479,1504 **** mod = choose_mod[(unsigned char)*tstr]; arg = NULL; ! if (mod != NULL && (!mod->atstart || atstart)) arg = mod->getarg(&tstr, ctxt, err, endc); ! if (FEATURES(FEATURE_SYSVVARSUB) && arg == NULL) { mod = &sysv_mod; arg = mod->getarg(&tstr, ctxt, err, endc); } - atstart = false; if (arg != NULL) { ! if (str != NULL || (mod->atstart && name != NULL)) { if (mod->word_apply != NULL) { newStr = VarModify(str, mod->word_apply, arg); ! if (mod->apply != NULL) { ! char *newStr2; ! ! newStr2 = mod->apply(newStr, ! name, arg); ! free(newStr); ! newStr = newStr2; ! } } else newStr = mod->apply(str, name, arg); if (*freePtr) --- 1116,1133 ---- mod = choose_mod[(unsigned char)*tstr]; arg = NULL; ! if (mod != NULL) arg = mod->getarg(&tstr, ctxt, err, endc); ! if (arg == NULL) { mod = &sysv_mod; arg = mod->getarg(&tstr, ctxt, err, endc); } if (arg != NULL) { ! if (str != NULL) { if (mod->word_apply != NULL) { newStr = VarModify(str, mod->word_apply, arg); ! assert(mod->apply == NULL); } else newStr = mod->apply(str, name, arg); if (*freePtr)