=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/make/parsevar.c,v retrieving revision 1.15 retrieving revision 1.16 diff -c -r1.15 -r1.16 *** src/usr.bin/make/parsevar.c 2013/11/22 15:47:35 1.15 --- src/usr.bin/make/parsevar.c 2016/10/23 14:54:14 1.16 *************** *** 1,4 **** ! /* $OpenBSD: parsevar.c,v 1.15 2013/11/22 15:47:35 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* --- 1,4 ---- ! /* $OpenBSD: parsevar.c,v 1.16 2016/10/23 14:54:14 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* *************** *** 79,84 **** --- 79,86 ---- #define VAR_APPEND 2 #define VAR_SHELL 4 #define VAR_OPT 8 + #define VAR_LAZYSHELL 16 + #define VAR_SUNSHELL 32 int type; struct Name name; *************** *** 90,100 **** type = VAR_NORMAL; while (*arg != '=') { /* Check operator type. */ switch (*arg++) { case '+': ! if (type & (VAR_OPT|VAR_APPEND)) type = VAR_INVALID; else type |= VAR_APPEND; --- 92,105 ---- type = VAR_NORMAL; + /* double operators (except for :) are forbidden */ + /* OPT and APPEND don't match */ + /* APPEND and LAZYSHELL can't really work */ while (*arg != '=') { /* Check operator type. */ switch (*arg++) { case '+': ! if (type & (VAR_OPT|VAR_LAZYSHELL|VAR_APPEND)) type = VAR_INVALID; else type |= VAR_APPEND; *************** *** 110,116 **** case ':': if (FEATURES(FEATURE_SUNSHCMD) && strncmp(arg, "sh", 2) == 0) { ! type = VAR_SHELL; arg += 2; while (*arg != '=' && *arg != '\0') arg++; --- 115,121 ---- case ':': if (FEATURES(FEATURE_SUNSHCMD) && strncmp(arg, "sh", 2) == 0) { ! type = VAR_SUNSHELL; arg += 2; while (*arg != '=' && *arg != '\0') arg++; *************** *** 123,129 **** break; case '!': ! if (type & VAR_SHELL) type = VAR_INVALID; else type |= VAR_SHELL; --- 128,139 ---- break; case '!': ! if (type & VAR_SHELL) { ! if (type & (VAR_APPEND)) ! type = VAR_INVALID; ! else ! type = VAR_LAZYSHELL; ! } else if (type & (VAR_LAZYSHELL|VAR_SUNSHELL)) type = VAR_INVALID; else type |= VAR_SHELL; *************** *** 147,153 **** VarName_Free(&name); return true; } ! if (type & VAR_SHELL) { char *err; if (strchr(arg, '$') != NULL) { --- 157,163 ---- VarName_Free(&name); return true; } ! if (type & (VAR_SHELL|VAR_SUNSHELL)) { char *err; if (strchr(arg, '$') != NULL) { *************** *** 164,169 **** --- 174,186 ---- Parse_Error(PARSE_WARNING, err, arg); arg = res1; } + if (type & VAR_LAZYSHELL) { + if (strchr(arg, '$') != NULL) { + /* There's a dollar sign in the command, so perform + * variable expansion on the whole thing. */ + arg = Var_Subst(arg, NULL, true); + } + } if (type & VAR_SUBST) { /* * Allow variables in the old value to be undefined, but leave *************** *** 195,200 **** --- 212,219 ---- Var_Appendi_with_ctxt(name.s, name.e, arg, ctxt); else Var_Seti_with_ctxt(name.s, name.e, arg, ctxt); + if (type & VAR_LAZYSHELL) + Var_Mark(name.s, name.e, VAR_EXEC_LATER); VarName_Free(&name); free(res2);