wordsplit/tests/wordsplit.at
Sergey Poznyakoff d97c672079 Pull fixes from mailutils
This includes the following commits pushed between
2015-09-19 and 2017-10-10:

090c7b9a       Allow ws_getvar to set value to NULL and
return MU_WRDSE_OK.
The value is processed as if it were "", i.e.
MU_WRDSE_UNDEF is returned.
64313fdf       Fix MU_WRDSF_INCREMENTAL | MU_WRDSF_NOSPLIT
46d7640f       Add wordsplit_append function
151eb4b9       Fix nested expansions and command expansions
occurring after variable expansions.
ad3cc340       Replace void wordsplit_getwords with
int wordsplit_get_words.

* include/wordsplit.h (wordsplit_get_words): New function.
(wordsplit_getwords): Mark as deprecated.
(wordsplit_append): New function.
* src/wordsplit.c (wordsplit_append): New function. MU 46d7640f.
(expvar): Treat NULL value as "". MU 090c7b9a.

(expcmd): Allow command and variable expansions in subsplit.
(exptab): Change ordering of expansions so that command expansion
occurs first. This fixes nested expansions and command expansions
occurring after variable expansions. MU 151eb4b9.

(wordsplit_process_list): Update wsp->ws_endp in nosplit mode. This
fixes wordsplit MU_WRDSF_INCREMENTAL | MU_WRDSF_NOSPLIT. MU 64313fdf.

(wordsplit_get_words): New function. MU ad3cc340.

* tests/wordsplit.at: Test the above changes.
* tests/wsp.c: Accept extra arguments to append using wordsplit_append.
2017-11-10 10:42:12 +02:00

884 lines
13 KiB
Text
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This file is part of grecs -*- Autotest -*-
# Copyright (C) 2014-2016 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 <http://www.gnu.org/licenses/>.
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
])
TESTWSP([quoted space],[wsp-quoted],[],
[quoted\ space],
[NF: 1
0: "quoted space"
])
TESTWSP([tab character],[wsp-tab],[],
[a "tab character"],
[NF: 2
0: a
1: tab\tcharacter
])
WSPGROUP(wsp-escape)
TESTWSP([octal and hex escapes],[],[],
[\157\143\164\141\154\40and\x20\x68\x65\x78],
[NF: 1
0: "octal and hex"
])
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"
])
TESTWSP([escape representation],[],[],
[A\x3-\48\39],
[NF: 1
0: A\003-\0048\0039
])
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
NF: 4
0: jeden
1: dwa
2: trzy
3: cztery
NF: 6
0: jeden
1: dwa
2: trzy
3: cztery
4: piec
5: szesc
])
TESTWSP([dooffs],[wsp-doofs ],[dooffs 3 jeden dwa trzy],
[cztery piec],
[NF: 2 (3)
(0): jeden
(1): dwa
(2): trzy
3: cztery
4: piec
])
WSPGROUP(wsp-var)
TESTWSP([variable substitutions: single var],[],[],
[a $FOO test],
[NF: 3
0: a
1: bar
2: test
],
[],
[FOO=bar])
TESTWSP([variable substitutions: concatenated vars],[],
[],
[a $FOO${BAR}ent test],
[NF: 3
0: a
1: stringent
2: test
],
[],
[FOO=str BAR=ing])
TESTWSP([variable substitutions: field splitting],[],[],
[a $FOO test],
[NF: 4
0: a
1: variable
2: substitution
3: test
],
[],
[FOO="variable substitution"])
TESTWSP([variable substitutions: double-quoted variable],[],[],
[a "$FOO" test],
[NF: 3
0: a
1: "variable substitution"
2: test
],
[],
[FOO="variable substitution"])
TESTWSP([variable substitutions: single-quoted variable],[],[],
[a '$FOO' test],
[NF: 3
0: a
1: $FOO
2: test
],
[],
[FOO="variable substitution"])
TESTWSP([undefined variables 1],[],[],
[a $FOO test a${FOO}b],
[NF: 3
0: a
1: test
2: ab
],
[],
[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
],
[],
[unset FOO;])
TESTWSP([warn about undefined variables],[],[warnundef],
[$FOO],
[NF: 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
],
[],
[FOO=bar])
TESTWSP([K/V environment],[wsp-env-kv wsp-env_kv],
[env_kv],
[$FOO a$BAZ],
[NF: 2
0: bar
1: aqux
],
[],
[FOO=bar BAZ=qux])
TESTWSP([nosplit with expansion],[wsp-var-nosplit],[nosplit],
[a $FOO test],
[NF: 1
0: "a variable expansion test\n"
],
[],
[FOO="variable expansion"])
TESTWSP([nosplit without expansion],[],[nosplit novar],
[a $FOO test],
[NF: 1
0: "a $FOO test\n"
],
[],
[FOO="variable expansion"])
TESTWSP([default value (defined)],[],[],
[${FOO:-bar}],
[NF: 1
0: qux
],
[],
[FOO=qux])
TESTWSP([default value],[],[],
[${FOO:-bar}],
[NF: 1
0: bar
])
TESTWSP([default value (defined)],[],[],
[${FOO:-bar}],
[NF: 1
0: qux
],
[],
[FOO=qux])
TESTWSP([default value (:- null)],[],[],
[${FOO:-bar}],
[NF: 1
0: bar
],
[],
[FOO=])
TESTWSP([default value (- null)],[],[],
[${FOO-bar}],
[NF: 0
],
[],
[FOO=])
TESTWSP([default value (- null, unset)],[],[],
[${FOO-bar}],
[NF: 1
0: bar
])
TESTWSP([assign default values],[],[],
[${FOO=bar}
$FOO],
[NF: 1
0: bar
NF: 1
0: bar
])
TESTWSP([default error message (var defined)],[],[],
[a ${FOO:?} test],
[NF: 3
0: a
1: bar
2: test
],
[],
[FOO=bar])
TESTWSP([default error message],[],[],
[${FOO:?}],
[NF: 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
],
[],
[FOO=bar])
TESTWSP([custom error message],[wsp-custom-err wsp-custom-err01],[],
[a ${FOO:?please define it} test],
[NF: 2
0: a
1: test
],
[FOO: please define it
])
TESTWSP([alternate value (defined)],[wsp-alt wsp-alt00],[],
[a ${FOO:+isset} test],
[NF: 3
0: a
1: isset
2: test
],
[],
[FOO=bar])
TESTWSP([alternate value],[wsp-alt wsp-alt01],[],
[a ${FOO:+isset} test],
[NF: 2
0: a
1: test
],
[],
[unset FOO;])
TESTWSP([getvar],[wsp-getvar],
[foo=bar x=quux],
[begin $foo $x end],
[NF: 4
0: begin
1: bar
2: quux
3: end
],
[],
[],
[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
],
[],
[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
])
WSPGROUP()
TESTWSP([ignore quotes],[wsp-ignore-quotes ],[-quote],
["a text"],
[NF: 2
0: "\"a"
1: "text\""
])
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
])
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
])
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
])
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
])
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
])
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
])
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
])
TESTWSP([ws elimination],[wsp-ws-elim],[delim ' ()' ws return_delims],
[( list items )],
[NF: 4
0: (
1: list
2: items
3: )
])
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
])
TESTWSP([empty quotes],[wsp-empty-quotes],[delim : ws return_delims],
[t=""],
[NF: 1
0: t=
])
TESTWSP([delimiter following empty quotes],
[],[delim : ws return_delims],
[t="":r],
[NF: 3
0: t=
1: :
2: r
])
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}, "
])
TESTWSP([unescape],
[wsp-unescape wsp-unescape-simple],
[-default novar nocmd quote escape ':+:\\""'],
[\Seen "quote \"" "bs \\"],
[NF: 3
0: \\Seen
1: "quote \""
2: "bs \\"
])
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
])
TESTWSP([dquote],[],[-default novar nocmd dquote],
[a "quoted example" isn't it],
[NF: 4
0: a
1: "quoted example"
2: isn't
3: it
])
TESTWSP([squote],[],[-default novar nocmd squote],
[a 'quoted example' isn"t it],
[NF: 4
0: a
1: "quoted example"
2: "isn\"t"
3: it
])
WSPGROUP(wsp-incr)
TESTWSP([incremental],[],[incremental],
[incremental "input test" line
],
[NF: 1
0: incremental
NF: 1
0: "input test"
NF: 1
0: line
],
[input exhausted
])
TESTWSP([incremental append],[],[incremental append],
[incremental "input test" line
],
[NF: 1
0: incremental
NF: 2
0: incremental
1: "input test"
NF: 3
0: incremental
1: "input test"
2: line
],
[input exhausted
])
TESTWSP([incremental ws],
[],[return_delims -squeeze_delims incremental ws],
[a list test
],
[NF: 1
0: a
NF: 1
0: list
NF: 1
0: test
],
[input exhausted
])
TESTWSP([incremental nosplit],[],[incremental nosplit],
[incremental "input test" line
],
[NF: 1
0: "incremental \"input test\" line"
],
[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
])
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
])
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
])
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"
])
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
])
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"
])
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
])
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
])
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
])
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
])
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
])
TESTWSP([append + dooffs + 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
])
m4_popdef([TESTWSP])
m4_popdef([wspnum])
m4_popdef([wspid])
m4_popdef([genkw])
m4_popdef([wspgroupnum])
m4_popdef([wspgroupname])
m4_popdef([WSPGROUP])