aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2014-09-09 08:52:06 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-12-17 15:24:37 +0200
commit6b41f7cb1fb39932b53551715b35823a0c8af4f1 (patch)
treed4175a8c0ffe08ef639dad1366863d5a46d6747c
parentfe9bc685c39e79c892bf234163e7fed903c1362d (diff)
downloadgrecs-6b41f7cb1fb39932b53551715b35823a0c8af4f1.tar.gz
grecs-6b41f7cb1fb39932b53551715b35823a0c8af4f1.tar.bz2
wordsplit: Fix expansion of ${...}
* src/wordsplit.c (expvar): Ensure value is set. Pass WRDSF_QUOTE to wordsplit (scan_word): Treat ${...} as a single word. * tests/wordsplit.at: Add more tests. * tests/wsp.c: Fix error message.
-rw-r--r--src/wordsplit.c16
-rw-r--r--tests/wordsplit.at68
-rw-r--r--tests/wsp.c2
3 files changed, 80 insertions, 6 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index dbb5aa5..4605e2e 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -612,8 +612,7 @@ node_split_prefix (struct wordsplit *wsp,
static int
find_closing_cbrace (const char *str, size_t i, size_t len, size_t * poff)
{
- enum
- { st_init, st_squote, st_dquote } state = st_init;
+ enum { st_init, st_squote, st_dquote } state = st_init;
size_t level = 1;
for (; i < len; i++)
@@ -779,7 +778,9 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
}
else if (wsp->ws_flags & WRDSF_GETVAR)
value = wsp->ws_getvar (str, i, wsp->ws_closure);
-
+ else
+ value = NULL;
+
if (!value)
{
if (defstr)
@@ -866,7 +867,8 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
ws.ws_delim = wsp->ws_delim;
rc = wordsplit (value, &ws,
- WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_WS);
+ WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM |
+ WRDSF_WS | WRDSF_QUOTE);
free (value);
if (rc)
{
@@ -1192,7 +1194,11 @@ scan_word (struct wordsplit *wsp, size_t start)
}
}
- if (ISDELIM (wsp, command[i]))
+ if (!(wsp->ws_flags & WRDSF_NOVAR)
+ && command[i] == '$' && command[i+1] == '{'
+ && find_closing_cbrace (command, i + 2, len, &i) == 0)
+ continue;
+ else if (ISDELIM (wsp, command[i]))
break;
else
i++;
diff --git a/tests/wordsplit.at b/tests/wordsplit.at
index d74cbe9..d87fa74 100644
--- a/tests/wordsplit.at
+++ b/tests/wordsplit.at
@@ -438,4 +438,72 @@ NF: 1
[input exhausted
])
+TESTWSP([default value (defined)],[wsp-var wsp-var13 wsp39],[],
+[${FOO:-bar}],
+[NF: 1
+0: qux
+],
+[],
+[FOO=qux])
+
+TESTWSP([default value],[wsp-var wsp-var14 wsp40],[],
+[${FOO:-bar}],
+[NF: 1
+0: bar
+])
+
+TESTWSP([default error message (var defined)],[wsp-var wsp-var15 wsp41],[],
+[a ${FOO:?} test],
+[NF: 3
+0: a
+1: bar
+2: test
+],
+[],
+[FOO=bar])
+
+TESTWSP([default error message],[wsp-var wsp-var16 wsp42],[],
+[${FOO:?}],
+[NF: 0
+],
+[FOO: variable null or not set
+])
+
+TESTWSP([custom error message (defined)],[wsp-var wsp-var17 wsp43],[],
+[a ${FOO:?please define it} test],
+[NF: 3
+0: a
+1: bar
+2: test
+],
+[],
+[FOO=bar])
+
+TESTWSP([custom error message],[wsp-var wsp-var18 wsp44],[],
+[a ${FOO:?please define it} test],
+[NF: 2
+0: a
+1: test
+],
+[FOO: please define it
+])
+
+TESTWSP([alternate value (defined)],[wsp-var wsp-var19 wsp45],[],
+[a ${FOO:+isset} test],
+[NF: 3
+0: a
+1: isset
+2: test
+],
+[],
+[FOO=bar])
+
+TESTWSP([alternate value],[wsp-var wsp-var20 wsp46],[],
+[a ${FOO:+isset} test],
+[NF: 2
+0: a
+1: test
+])
+
+
m4_popdef([TESTWSP])
diff --git a/tests/wsp.c b/tests/wsp.c
index e06008f..e929de7 100644
--- a/tests/wsp.c
+++ b/tests/wsp.c
@@ -296,7 +296,7 @@ main (int argc, char **argv)
continue;
}
- fprintf (stderr, "%s: unrecognized argument for %s\n",
+ fprintf (stderr, "%s: unrecognized argument: %s\n",
progname, opt);
exit (1);
}

Return to:

Send suggestions and report system problems to the System administrator.