diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-11-15 09:58:01 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-11-15 09:58:01 +0200 |
commit | 6e4ef4c272a23ffde227689bc4e65a0523f18b4d (patch) | |
tree | 9c47e8915e0a11ff5df86ee7849cbc54eeff3882 /tests | |
parent | 82a4e4b019194d60080c1b9f34de841485f3b9e3 (diff) | |
download | grecs-6e4ef4c272a23ffde227689bc4e65a0523f18b4d.tar.gz grecs-6e4ef4c272a23ffde227689bc4e65a0523f18b4d.tar.bz2 |
Port mailutils commit 2c2e3c50d6
* include/wordsplit.h (WRDSO_ARGV): Remove.
* src/wordsplit.c (expcmd): Always split command line into arguments.
This fixes https://savannah.gnu.org/bugs/?54830
* tests/wsp.c: Implement internal commands, instead of
calling shell ones. This fixes https://savannah.gnu.org/bugs/?54829.
* tests/wordsplit.at: Rewrite command expansion tests.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/wordsplit.at | 138 | ||||
-rw-r--r-- | tests/wsp.c | 131 |
2 files changed, 111 insertions, 158 deletions
diff --git a/tests/wordsplit.at b/tests/wordsplit.at index 75dde85..631d939 100644 --- a/tests/wordsplit.at +++ b/tests/wordsplit.at @@ -711,142 +711,70 @@ TOTAL: 1 ], [input exhausted ]) - -dnl Something that doesn't fit into TESTWSP - -AT_SETUP([simple command substitution]) -AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-1]) -AT_CHECK([ -mkdir dir -> dir/file - -wsp -nocmd <<'EOT' -begin $(find dir) end -EOT -], -[0], + +TESTWSP([simple command substitution],[],[-nocmd], +[begin $(words a b) end], [NF: 4 0: begin -1: dir -2: dir/file +1: a +2: b 3: end TOTAL: 4 ]) -AT_CLEANUP -AT_SETUP([quoted command substitution]) -AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-2]) -AT_CHECK([ -mkdir dir -> dir/file - -wsp -nocmd <<'EOT' -begin "$(find dir)" end -EOT -], -[0], +TESTWSP([quoted command substitution],[],[-nocmd], +[begin "$(words a b)" end], [NF: 3 0: begin -1: "dir dir/file" +1: "a b" 2: end TOTAL: 3 ]) -AT_CLEANUP - -AT_SETUP([coalesced command substitution]) -AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-3]) -AT_CHECK([ -mkdir dir -> dir/file -wsp -nocmd <<'EOT' -begin($(find dir))end -EOT -], -[0], +TESTWSP([coalesced command substitution],[],[-nocmd], +[begin($(words a b))end], [NF: 2 -0: begin(dir -1: dir/file)end +0: begin(a +1: b)end TOTAL: 2 ]) -AT_CLEANUP -AT_SETUP([quoted coalesced command substitution]) -AT_KEYWORDS([wordsplit wsp wsp-cmd wsp-cmd-4]) -AT_CHECK([ -mkdir dir -> dir/file - -wsp -nocmd <<'EOT' -"begin($(find dir))end" -EOT -], -[0], +TESTWSP([quoted coalesced command substitution],[],[-nocmd], +["begin($(words a b))end"], [NF: 1 -0: "begin(dir dir/file)end" +0: "begin(a b)end" TOTAL: 1 ]) -AT_CLEANUP - -AT_SETUP([variable and command substitution]) -AT_KEYWORDS([wordsplit wsp wsp-var wsp-var24 wsp-cmd wsp-cmd-5]) -AT_CHECK([ -mkdir dir -> dir/file -DIR=dir wsp -nocmd -novar<<'EOT' -begin $DIR $(find $DIR) end -EOT -], -[0], +TESTWSP([variable and command substitution],[],[-nocmd -novar], +[begin $X $(words $X $Y) end], [NF: 5 0: begin -1: dir -2: dir -3: dir/file +1: a +2: a +3: b 4: end TOTAL: 5 -]) -AT_CLEANUP +],[],[X=a Y=b]) -AT_SETUP([variable expansion and command substitution in quotes]) -AT_KEYWORDS([wordsplit wsp wsp-var wsp-var25 wsp-cmd wsp-cmd-6]) -AT_CHECK([ -mkdir dir -> dir/file - -DIR=dir BEGIN=begin wsp -nocmd -novar<<'EOT' -"${BEGIN}($(find $DIR))end" -EOT -], -[0], +TESTWSP([variable expansion and command substitution in quotes],[],[-nocmd -novar], +["${BEGIN}($(words $X $Y))end"], [NF: 1 -0: "begin(dir dir/file)end" +0: "begin(a b)end" TOTAL: 1 -]) -AT_CLEANUP - -AT_SETUP([nested commands]) -AT_KEYWORDS([wordsplit wsp wsp-cmd]) -AT_CHECK([ -AT_DATA([input],[foo -bar -baz -]) -SUFFIX=put wsp -nocmd -novar <<'EOT' -$(echo output $(cat in$SUFFIX)) -EOT -], -[0], +],[],[X=a Y=b BEGIN=begin]) + +TESTWSP([nested commands],[],[-nocmd -novar], +[$(words output $(words in$SUFFIX text) end)], [NF: 4 0: output -1: foo -2: bar -3: baz +1: input +2: text +3: end TOTAL: 4 -]) -AT_CLEANUP +],[],[SUFFIX=put]) +dnl Something that doesn't fit into TESTWSP AT_SETUP([pathname expansion]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-1]) AT_CHECK([ diff --git a/tests/wsp.c b/tests/wsp.c index a96fb7f..cca3a36 100644 --- a/tests/wsp.c +++ b/tests/wsp.c @@ -201,72 +201,97 @@ wsp_getvar (char **ret, const char *vptr, size_t vlen, void *data) } return WRDSE_UNDEF; } - + static int -wsp_runcmd (char **ret, const char *str, size_t len, char **argv, void *closure) +cmd_quote (char **ret, const char *str, size_t len, char **argv) { - FILE *fp; - char *cmd; - int c, lastc; - char *buffer = NULL; - size_t bufsize = 0; - size_t buflen = 0; + int alen; + for (alen = 0; alen < len && !(str[alen] == ' ' || str[alen] == '\t'); alen++) + ; + for (; alen < len && (str[alen] == ' ' || str[alen] == '\t'); alen++) + ; + len -= alen; + *ret = malloc (len + 1); + if (!*ret) + return WRDSE_NOSPACE; + memcpy (*ret, str + alen, len); + (*ret)[len] = 0; + return WRDSE_OK; +} + +static int +cmd_words (char **ret, const char *str, size_t len, char **argv) +{ + char *p; + int i; - cmd = malloc (len + 1); - if (!cmd) + p = malloc (len + 1); + if (!p) return WRDSE_NOSPACE; - memcpy (cmd, str, len); - cmd[len] = 0; - - fp = popen(cmd, "r"); - if (!fp) + *ret = p; + for (i = 1; argv[i]; i++) { - size_t size = 0; - ret = NULL; - if (grecs_asprintf (ret, &size, "can't run %s: %s", - cmd, strerror (errno))) - return WRDSE_NOSPACE; - else - return WRDSE_USERERR; + size_t s = strlen (argv[i]); + if (i > 1) + *p++ = ' '; + memcpy (p, argv[i], s); + p += s; } + *p = 0; + return WRDSE_OK; +} - while ((c = fgetc (fp)) != EOF) +static int +cmd_lines (char **ret, const char *str, size_t len, char **argv) +{ + char *p; + int i; + + p = malloc (len + 1); + if (!p) + return WRDSE_NOSPACE; + *ret = p; + for (i = 1; argv[i]; i++) { - lastc = c; - if (c == '\n') - c = ' '; - if (buflen == bufsize) - { - char *p; - - if (bufsize == 0) - bufsize = 80; - else - bufsize *= 2; - p = realloc (buffer, bufsize); - if (!p) - { - free (buffer); - free (cmd); - return WRDSE_NOSPACE; - } - buffer = p; - } - buffer[buflen++] = c; + size_t s = strlen (argv[i]); + if (i > 1) + *p++ = '\n'; + memcpy (p, argv[i], s); + p += s; } + *p = 0; + return WRDSE_OK; +} + +static struct command +{ + char const *name; + int (*cmd)(char **ret, const char *str, size_t len, char **argv); +} comtab[] = { + { "quote", cmd_quote }, + { "words", cmd_words }, + { "lines", cmd_lines } +}; - if (buffer) +static int +wsp_runcmd (char **ret, const char *str, size_t len, char **argv, void *closure) +{ + int i; + size_t s = 0; + + for (i = 0; ; i++) { - if (lastc == '\n') - --buflen; - buffer[buflen] = 0; + if (i == sizeof (comtab) / sizeof (comtab[0])) + break; + if (strcmp (comtab[i].name, argv[0]) == 0) + return comtab[i].cmd (ret, str, len, argv); } - - pclose (fp); - free (cmd); - *ret = buffer; - return WRDSE_OK; + *ret = NULL; + if (grecs_asprintf (ret, &s, "unknown command: %s", argv[0])) + return WRDSE_NOSPACE; + else + return WRDSE_USERERR; } enum env_type |