# This file is part of grecs -*- Autotest -*- # Copyright (C) 2014-2018 Sergey Poznyakoff # # Grecs is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # Grecs is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Grecs. If not, see . AT_BANNER(Wordsplit) m4_pushdef([wspnum],[0]) m4_pushdef([wspid]) m4_pushdef([wspgroupnum]) m4_pushdef([wspgroupname]) m4_pushdef([genkw],[dnl m4_define([wspid],m4_format([wordsplit%03d wsp%03d],wspnum))dnl m4_if(wspgroupname,,,[m4_define([wspid],wspid[ ]dnl m4_format(wspgroupname[ ]wspgroupname[%03d],wspgroupnum))dnl m4_define([wspgroupnum],m4_incr(wspgroupnum))])dnl m4_define([wspnum],m4_incr(wspnum))dnl wspid]) m4_pushdef([WSPGROUP],[ m4_define([wspgroupname],$1) m4_define([wspgroupnum],0)]) dnl ------------------------------------------------------------ dnl TESTWSP([NAME], [KW = `'], [OPTS], [INPUT], [STDOUT = `'], dnl [STDERR = `'], [ENV], [PROLOGUE]) dnl m4_pushdef([TESTWSP],[ AT_SETUP([$1]) AT_KEYWORDS([wordsplit wsp ]genkw[ $2]) AT_CHECK([$8 $7 wsp $3 <<'EOT' [$4] EOT ], [0], [$5], [$6]) AT_CLEANUP ]) dnl ------------------------------------------------------------ dnl The first part reproduces legacy argcv tests dnl ------------------------------------------------------------ TESTWSP([simple input],[wsp-simple],[], [1 2 3], [NF: 3 0: 1 1: 2 2: 3 TOTAL: 3 ]) TESTWSP([quoted space],[wsp-quoted],[], [quoted\ space], [NF: 1 0: "quoted space" TOTAL: 1 ]) TESTWSP([tab character],[wsp-tab],[], [a "tab character"], [NF: 2 0: a 1: tab\tcharacter TOTAL: 2 ]) WSPGROUP(wsp-escape) TESTWSP([octal and hex escapes],[],[], [\157\143\164\141\154\40and\x20\x68\x65\x78], [NF: 1 0: "octal and hex" TOTAL: 1 ]) TESTWSP([octal and hex escapes 2],[],[], [\157\143\164\141\154\40 and \x20\x68\x65\x78], [NF: 3 0: "octal " 1: and 2: " hex" TOTAL: 3 ]) TESTWSP([escape representation],[],[], [A\x3-\48\39], [NF: 1 0: A\003-\0048\0039 TOTAL: 1 ]) WSPGROUP() dnl ------------------------------------------------------------ dnl Test worsplit-specific behavior dnl ------------------------------------------------------------ TESTWSP([append],[wsp-append],[append], [jeden dwa trzy cztery piec szesc], [NF: 3 0: jeden 1: dwa 2: trzy TOTAL: 3 NF: 4 0: jeden 1: dwa 2: trzy 3: cztery TOTAL: 1 NF: 6 0: jeden 1: dwa 2: trzy 3: cztery 4: piec 5: szesc TOTAL: 2 ]) TESTWSP([dooffs],[wsp-doofs ],[dooffs 3 jeden dwa trzy], [cztery piec], [NF: 2 (3) (0): jeden (1): dwa (2): trzy 3: cztery 4: piec TOTAL: 2 ]) WSPGROUP(wsp-var) TESTWSP([variable substitutions: single var],[],[], [a $FOO test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([variable substitutions: concatenated vars],[], [], [a $FOO${BAR}ent test], [NF: 3 0: a 1: stringent 2: test TOTAL: 3 ], [], [FOO=str BAR=ing]) TESTWSP([variable substitutions: field splitting],[],[], [a $FOO test], [NF: 4 0: a 1: variable 2: substitution 3: test TOTAL: 4 ], [], [FOO="variable substitution"]) TESTWSP([variable substitutions: double-quoted variable],[],[], [a "$FOO" test], [NF: 3 0: a 1: "variable substitution" 2: test TOTAL: 3 ], [], [FOO="variable substitution"]) TESTWSP([variable substitutions: single-quoted variable],[],[], [a '$FOO' test], [NF: 3 0: a 1: $FOO 2: test TOTAL: 3 ], [], [FOO="variable substitution"]) TESTWSP([undefined variables 1],[],[], [a $FOO test a${FOO}b], [NF: 3 0: a 1: test 2: ab TOTAL: 3 ], [], [unset FOO;]) TESTWSP([undefined variables 2],[],[keepundef], [a $FOO test a${FOO}b], [NF: 4 0: a 1: $FOO 2: test 3: a${FOO}b TOTAL: 4 ], [], [unset FOO;]) TESTWSP([warn about undefined variables],[],[warnundef], [$FOO], [NF: 0 TOTAL: 0 ], [warning: undefined variable `FOO' ], [unset FOO;]) TESTWSP([bail out on undefined variables],[],[undef], [$FOO], [], [undefined variable ], [unset FOO;]) TESTWSP([disable variable expansion],[],[novar], [$FOO], [NF: 1 0: $FOO TOTAL: 1 ], [], [FOO=bar]) TESTWSP([K/V environment],[wsp-env-kv wsp-env_kv], [env_kv], [$FOO a$BAZ], [NF: 2 0: bar 1: aqux TOTAL: 2 ], [], [FOO=bar BAZ=qux]) TESTWSP([nosplit with expansion],[wsp-var-nosplit],[nosplit], [a $FOO test], [NF: 1 0: "a variable expansion test\n" TOTAL: 1 ], [], [FOO="variable expansion"]) TESTWSP([nosplit without expansion],[],[nosplit novar], [a $FOO test], [NF: 1 0: "a $FOO test\n" TOTAL: 1 ], [], [FOO="variable expansion"]) TESTWSP([default value (defined)],[],[], [${FOO:-bar}], [NF: 1 0: qux TOTAL: 1 ], [], [FOO=qux]) TESTWSP([default value],[],[], [${FOO:-bar}], [NF: 1 0: bar TOTAL: 1 ]) TESTWSP([default value (defined)],[],[], [${FOO:-bar}], [NF: 1 0: qux TOTAL: 1 ], [], [FOO=qux]) TESTWSP([default value (:- null)],[],[], [${FOO:-bar}], [NF: 1 0: bar TOTAL: 1 ], [], [FOO=]) TESTWSP([default value (- null)],[],[], [${FOO-bar}], [NF: 0 TOTAL: 0 ], [], [FOO=]) TESTWSP([default value (- null, unset)],[],[], [${FOO-bar}], [NF: 1 0: bar TOTAL: 1 ]) TESTWSP([assign default values],[],[], [${FOO=bar} $FOO], [NF: 1 0: bar TOTAL: 1 NF: 1 0: bar TOTAL: 1 ]) TESTWSP([default error message (var defined)],[],[], [a ${FOO:?} test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([default error message],[],[], [${FOO:?}], [NF: 0 TOTAL: 0 ], [FOO: variable null or not set ]) TESTWSP([custom error message (defined)],[wsp-custom-err wsp-custom-err00],[], [a ${FOO:?please define it} test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([custom error message],[wsp-custom-err wsp-custom-err01],[], [a ${FOO:?please define it} test], [NF: 2 0: a 1: test TOTAL: 2 ], [FOO: please define it ]) TESTWSP([alternate value (defined)],[wsp-alt wsp-alt00],[], [a ${FOO:+isset} test], [NF: 3 0: a 1: isset 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([alternate value],[wsp-alt wsp-alt01],[], [a ${FOO:+isset} test], [NF: 2 0: a 1: test TOTAL: 2 ], [], [unset FOO;]) TESTWSP([getvar],[wsp-getvar], [foo=bar x=quux], [begin $foo $x end], [NF: 4 0: begin 1: bar 2: quux 3: end TOTAL: 4 ], [], [], [unset foo; unset x]) TESTWSP([getvar and env],[wsp-getvar], [foo=bar x=quux y=xur], [begin $foo $TVAR $x $y end], [NF: 6 0: begin 1: bar 2: 12 3: quux 4: zwar 5: end TOTAL: 6 ], [], [TVAR=12 y=zwar], [unset foo; unset x]) TESTWSP([getvar, alternate value],[wsp-getvar], [foo=bar], [a ${foo:+isset}], [NF: 2 0: a 1: isset TOTAL: 2 ]) WSPGROUP() TESTWSP([ignore quotes],[wsp-ignore-quotes ],[-quote], ["a text"], [NF: 2 0: "\"a" 1: "text\"" TOTAL: 2 ]) WSPGROUP(wsp-delim) TESTWSP([custom delimiters (squeeze)],[], [delim : -ws trimnl], [semicolon: separated::list: of :words], [NF: 5 0: semicolon 1: " separated" 2: list 3: " of " 4: words TOTAL: 5 ]) TESTWSP([custom delimiters (no squeeze)],[], [delim : -ws -squeeze_delims trimnl], [semicolon: separated::list: of :words], [NF: 6 0: semicolon 1: " separated" 2: "" 3: list 4: " of " 5: words TOTAL: 6 ]) TESTWSP([custom, with returned delimiters],[], [delim : -ws trimnl return_delims], [semicolon: separated::list: of :words], [NF: 9 0: semicolon 1: : 2: " separated" 3: : 4: list 5: : 6: " of " 7: : 8: words TOTAL: 9 ]) TESTWSP([custom, with returned & squeezed delimiters],[], [delim : -ws trimnl return_delims -squeeze_delims], [semicolon: separated::list: of :words], [NF: 10 0: semicolon 1: : 2: " separated" 3: : 4: : 5: list 6: : 7: " of " 8: : 9: words TOTAL: 10 ]) WSPGROUP(wsp-sed) TESTWSP([sed expressions],[],[sed], [arg1 s/foo/bar/g;s/bar baz/quz quux/ arg2], [NF: 3 0: arg1 1: "s/foo/bar/g;s/bar baz/quz quux/" 2: arg2 TOTAL: 3 ]) WSPGROUP() TESTWSP([C escapes on],[wcp-c-escape],[cescapes], [a\ttab form\ffeed and new\nline], [NF: 4 0: a\ttab 1: form\ffeed 2: and 3: new\nline TOTAL: 4 ]) TESTWSP([C escapes off],[wcp-c-escape-off],[-cescapes], [a\ttab form\ffeed and new\nline], [NF: 4 0: attab 1: formffeed 2: and 3: newnline TOTAL: 4 ]) TESTWSP([ws elimination],[wsp-ws-elim],[delim ' ()' ws return_delims], [( list items )], [NF: 4 0: ( 1: list 2: items 3: ) TOTAL: 4 ]) TESTWSP([ws elimination + return delim],[wsp-ws-elim-ret], [-default novar nocmd delim ":," return_delims ws dquote], ["foo" : "bar", "quux" : "baaz" ], [NF: 7 0: foo 1: : 2: bar 3: , 4: quux 5: : 6: baaz TOTAL: 7 ]) TESTWSP([empty quotes],[wsp-empty-quotes],[delim : ws return_delims], [t=""], [NF: 1 0: t= TOTAL: 1 ]) TESTWSP([delimiter following empty quotes], [],[delim : ws return_delims], [t="":r], [NF: 3 0: t= 1: : 2: r TOTAL: 3 ]) TESTWSP([suppress ws trimming within quotes], [], [default delim , ws return_delims], [nocomponent,nonewline, formatfield="In message %{text}, "], [NF: 5 0: nocomponent 1: , 2: nonewline 3: , 4: "formatfield=In message %{text}, " TOTAL: 5 ]) TESTWSP([unescape], [wsp-unescape wsp-unescape-simple], [-default novar nocmd quote escape ':+:\\""'], [\Seen "quote \"" "bs \\"], [NF: 3 0: \\Seen 1: "quote \"" 2: "bs \\" TOTAL: 3 ]) TESTWSP([unescape: word/quote], [wsp-unescape wsp-unescape-word], [-default novar nocmd quote escape-word '\\""' escape-quote ':+0x:\\""'], [\Seen "quote \"" "bs \\" "3\x31 \101" 3\x31 \101], [NF: 6 0: Seen 1: "quote \"" 2: "bs \\" 3: "31 A" 4: 3x31 5: 101 TOTAL: 6 ]) TESTWSP([dquote],[],[-default novar nocmd dquote], [a "quoted example" isn't it], [NF: 4 0: a 1: "quoted example" 2: isn't 3: it TOTAL: 4 ]) TESTWSP([squote],[],[-default novar nocmd squote], [a 'quoted example' isn"t it], [NF: 4 0: a 1: "quoted example" 2: "isn\"t" 3: it TOTAL: 4 ]) WSPGROUP(wsp-incr) TESTWSP([incremental],[],[incremental], [incremental "input test" line ], [NF: 1 0: incremental TOTAL: 1 NF: 1 0: "input test" TOTAL: 2 NF: 1 0: line TOTAL: 3 ], [input exhausted ]) TESTWSP([incremental append],[],[incremental append], [incremental "input test" line ], [NF: 1 0: incremental TOTAL: 1 NF: 2 0: incremental 1: "input test" TOTAL: 2 NF: 3 0: incremental 1: "input test" 2: line TOTAL: 3 ], [input exhausted ]) TESTWSP([incremental ws], [],[return_delims -squeeze_delims incremental ws], [a list test ], [NF: 1 0: a TOTAL: 1 NF: 1 0: list TOTAL: 2 NF: 1 0: test TOTAL: 3 ], [input exhausted ]) TESTWSP([incremental nosplit],[],[incremental nosplit], [incremental "input test" line ], [NF: 1 0: "incremental input test line" 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], [NF: 4 0: begin 1: dir 2: dir/file 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], [NF: 3 0: begin 1: "dir dir/file" 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], [NF: 2 0: begin(dir 1: dir/file)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], [NF: 1 0: "begin(dir dir/file)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], [NF: 5 0: begin 1: dir 2: dir 3: dir/file 4: end TOTAL: 5 ]) AT_CLEANUP 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], [NF: 1 0: "begin(dir dir/file)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], [NF: 4 0: output 1: foo 2: bar 3: baz TOTAL: 4 ]) AT_CLEANUP AT_SETUP([pathname expansion]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-1]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.c > dir/3.b wsp pathexpand<<'EOT' begin dir/*.c end EOT ], [0], [NF: 4 0: begin 1: dir/1.c 2: dir/2.c 3: end TOTAL: 4 ]) AT_CLEANUP AT_SETUP([pathname expansion: no match]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-2]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.b wsp pathexpand<<'EOT' begin dir/*.d end EOT ], [0], [NF: 3 0: begin 1: dir/*.d 2: end TOTAL: 3 ]) AT_CLEANUP AT_SETUP([pathname expansion: nullglob]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-3]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.b wsp pathexpand nullglob<<'EOT' begin dir/*.d end EOT ], [0], [NF: 2 0: begin 1: end TOTAL: 2 ]) AT_CLEANUP AT_SETUP([pathname expansion: failglob]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-4]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.b wsp pathexpand failglob<<'EOT' begin dir/*.d end EOT ], [0], [], [no files match pattern dir/*.d ]) AT_CLEANUP TESTWSP([append],[],[-- extra arguments follow], [some words and], [NF: 6 0: some 1: words 2: and 3: extra 4: arguments 5: follow TOTAL: 3 ]) TESTWSP([append + dooffs + env],[], [-env dooffs 2 preface words V=2 -- extra arguments follow], [some words and var=$V], [NF: 7 (2) (0): preface (1): words 2: some 3: words 4: and 5: var=2 6: extra 7: arguments 8: follow TOTAL: 4 ]) # Maxwords TESTWSP([maxwords],[], [trimnl maxwords 3], [ws_maxwords limits the number of returned words], [NF: 3 0: ws_maxwords 1: limits 2: "the number of returned words" TOTAL: 3 ]) TESTWSP([maxwords return_delims],[], [trimnl maxwords 8 return_delims delim :-], [foo:::bar-:baz-quux:ux:zu], [NF: 8 0: foo 1: : 2: bar 3: - 4: : 5: baz 6: - 7: quux:ux:zu TOTAL: 8 ]) TESTWSP([maxwords return_delims -squeeze_delims],[], [trimnl maxwords 8 return_delims -squeeze_delims delim :-], [foo:::bar-:baz:qux-], [NF: 8 0: foo 1: : 2: : 3: : 4: bar 5: - 6: : 7: baz:qux- TOTAL: 8 ]) TESTWSP([maxwords incremental],[], [trimnl maxwords 3 incremental], [foo bar baz qux uz ], [NF: 1 0: foo TOTAL: 1 NF: 1 0: bar TOTAL: 2 NF: 1 0: "baz qux uz" TOTAL: 3 ], [input exhausted ])) m4_popdef([TESTWSP]) m4_popdef([wspnum]) m4_popdef([wspid]) m4_popdef([genkw]) m4_popdef([wspgroupnum]) m4_popdef([wspgroupname]) m4_popdef([WSPGROUP])