diff options
Diffstat (limited to 'var.c')
-rw-r--r-- | var.c | 128 |
1 files changed, 113 insertions, 15 deletions
@@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $ */ +/* $NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.208 2016/06/03 01:21:59 sjg Exp $"); +__RCSID("$NetBSD: var.c,v 1.213 2017/02/01 18:39:27 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -2139,6 +2139,51 @@ VarUniq(const char *str) return Buf_Destroy(&buf, FALSE); } +/*- + *----------------------------------------------------------------------- + * VarRange -- + * Return an integer sequence + * + * Input: + * str String whose words provide default range + * ac range length, if 0 use str words + * + * Side Effects: + * None. + * + *----------------------------------------------------------------------- + */ +static char * +VarRange(const char *str, int ac) +{ + Buffer buf; /* Buffer for new string */ + char tmp[32]; /* each element */ + char **av; /* List of words to affect */ + char *as; /* Word list memory */ + int i, n; + + Buf_Init(&buf, 0); + if (ac > 0) { + as = NULL; + av = NULL; + } else { + av = brk_string(str, &ac, FALSE, &as); + } + for (i = 0; i < ac; i++) { + n = snprintf(tmp, sizeof(tmp), "%d", 1 + i); + if (n >= (int)sizeof(tmp)) + break; + Buf_AddBytes(&buf, n, tmp); + if (i != ac - 1) + Buf_AddByte(&buf, ' '); + } + + free(as); + free(av); + + return Buf_Destroy(&buf, FALSE); +} + /*- *----------------------------------------------------------------------- @@ -2380,12 +2425,12 @@ VarHash(char *str) } static char * -VarStrftime(const char *fmt, int zulu) +VarStrftime(const char *fmt, int zulu, time_t utc) { char buf[BUFSIZ]; - time_t utc; - time(&utc); + if (!utc) + time(&utc); if (!*fmt) fmt = "%c"; strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc)); @@ -2482,6 +2527,9 @@ VarStrftime(const char *fmt, int zulu) /* we now have some modifiers with long names */ #define STRMOD_MATCH(s, want, n) \ (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':')) +#define STRMOD_MATCHX(s, want, n) \ + (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':' || s[n] == '=')) +#define CHARMOD_MATCH(c) (c == endc || c == ':') static char * ApplyModifiers(char *nstr, const char *tstr, @@ -2493,12 +2541,14 @@ ApplyModifiers(char *nstr, const char *tstr, const char *cp; /* Secondary pointer into str (place marker * for tstr) */ char *newStr; /* New value to return */ + char *ep; char termc; /* Character which terminated scan */ int cnt; /* Used to count brace pairs when variable in * in parens or braces */ char delim; int modifier; /* that we are processing */ Var_Parse_State parsestate; /* Flags passed to helper functions */ + time_t utc; /* for VarStrftime */ delim = '\0'; parsestate.oneBigWord = FALSE; @@ -2690,6 +2740,28 @@ ApplyModifiers(char *nstr, const char *tstr, free(loop.str); break; } + case '_': /* remember current value */ + cp = tstr + 1; /* make sure it is set */ + if (STRMOD_MATCHX(tstr, "_", 1)) { + if (tstr[1] == '=') { + char *np; + int n; + + cp++; + n = strcspn(cp, ":)}"); + np = bmake_strndup(cp, n+1); + np[n] = '\0'; + cp = tstr + 2 + n; + Var_Set(np, nstr, ctxt, 0); + free(np); + } else { + Var_Set("_", nstr, ctxt, 0); + } + newStr = nstr; + termc = *cp; + break; + } + goto default_case; case 'D': case 'U': { @@ -2895,8 +2967,6 @@ ApplyModifiers(char *nstr, const char *tstr, * integer for :[N], or two integers * separated by ".." for :[start..end]. */ - char *ep; - VarSelectWords_t seldata = { 0, 0 }; seldata.start = strtol(estr, &ep, 0); @@ -2955,9 +3025,15 @@ ApplyModifiers(char *nstr, const char *tstr, } case 'g': cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "gmtime", 6)) { - newStr = VarStrftime(nstr, 1); - cp = tstr + 6; + if (STRMOD_MATCHX(tstr, "gmtime", 6)) { + if (tstr[6] == '=') { + utc = strtoul(&tstr[7], &ep, 10); + cp = ep; + } else { + utc = 0; + cp = tstr + 6; + } + newStr = VarStrftime(nstr, 1, utc); termc = *cp; } else { goto default_case; @@ -2975,9 +3051,15 @@ ApplyModifiers(char *nstr, const char *tstr, break; case 'l': cp = tstr + 1; /* make sure it is set */ - if (STRMOD_MATCH(tstr, "localtime", 9)) { - newStr = VarStrftime(nstr, 0); - cp = tstr + 9; + if (STRMOD_MATCHX(tstr, "localtime", 9)) { + if (tstr[9] == '=') { + utc = strtoul(&tstr[10], &ep, 10); + cp = ep; + } else { + utc = 0; + cp = tstr + 9; + } + newStr = VarStrftime(nstr, 0, utc); termc = *cp; } else { goto default_case; @@ -3026,7 +3108,6 @@ ApplyModifiers(char *nstr, const char *tstr, goto get_numeric; default: if (isdigit((unsigned char)tstr[3])) { - char *ep; get_numeric: parsestate.varSpace = @@ -3447,6 +3528,23 @@ ApplyModifiers(char *nstr, const char *tstr, break; } goto default_case; + case 'r': + cp = tstr + 1; /* make sure it is set */ + if (STRMOD_MATCHX(tstr, "range", 5)) { + int n; + + if (tstr[5] == '=') { + n = strtoul(&tstr[6], &ep, 10); + cp = ep; + } else { + n = 0; + cp = tstr + 5; + } + newStr = VarRange(nstr, n); + termc = *cp; + break; + } + goto default_case; case 'O': { char otype; |