365 lines
11 KiB
C++
365 lines
11 KiB
C++
/************************************************************************
|
|
*
|
|
* 0.braceexp.cpp - tests exercising the rw_brace_expand()
|
|
* and rw_shell_expand() helper functions
|
|
*
|
|
* $Id: 0.braceexp.cpp 648752 2008-04-16 17:01:56Z faridz $
|
|
*
|
|
************************************************************************
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#include <rw_braceexp.h>
|
|
#include <environ.h> // for rw_putenv()
|
|
|
|
#include <stdio.h> // for fprintf(), size_t, stderr
|
|
#include <stdlib.h> // for free()
|
|
#include <string.h> // for strcmp()
|
|
|
|
// the number of failed tests
|
|
static int nerrors;
|
|
|
|
static void
|
|
test (int line, const char* brace_expr, size_t n, const char* expect,
|
|
const char* fname,
|
|
char* (fn)(const char*, size_t, char*, size_t, char))
|
|
{
|
|
char buf [128];
|
|
|
|
char* result = fn (brace_expr, n, buf, sizeof (buf), ' ');
|
|
|
|
const bool equal = (expect && result)
|
|
? !strcmp (expect, result)
|
|
: expect == result;
|
|
|
|
if (!equal) {
|
|
|
|
++nerrors;
|
|
|
|
fprintf (stderr,
|
|
"%d. %s(\"%s\", ...) failed. "
|
|
"expected \"%s\" got \"%s\"\n",
|
|
line, fname, brace_expr,
|
|
expect ? expect : "(null)",
|
|
result ? result : "(null)");
|
|
}
|
|
|
|
if (result != buf)
|
|
free (result);
|
|
}
|
|
|
|
|
|
#define DO_TEST(s,e,f) test (__LINE__, s, strlen (s), e, #f, f)
|
|
#define TEST_COMMON(fn) run_tests (#fn, fn)
|
|
|
|
static void
|
|
run_tests (const char* fname,
|
|
char* (fn)(const char*, size_t, char*, size_t, char))
|
|
{
|
|
#undef TEST
|
|
#define TEST(s,e) test (__LINE__, s, strlen (s), e, fname, fn)
|
|
|
|
// run our tests
|
|
TEST ("", "");
|
|
|
|
// test plain and escaped whitespace
|
|
TEST ("\\ ", " ");
|
|
TEST ("\\ \\ ", " ");
|
|
TEST ("\\ \\\t\\ ", " \t ");
|
|
TEST ("a\\ b", "a b");
|
|
TEST ("a b", "a b");
|
|
|
|
TEST ("a", "a");
|
|
TEST ("a\\b", "ab");
|
|
|
|
TEST ("{", 0);
|
|
TEST ("}", "}");
|
|
TEST ("{}", "");
|
|
|
|
TEST ("}{", 0);
|
|
TEST ("}{}", "}");
|
|
TEST ("}{}{", 0);
|
|
TEST ("{{", 0);
|
|
TEST ("}}", "}}");
|
|
|
|
TEST ("{0}" , "0");
|
|
TEST ("\\{0}", "{0}");
|
|
TEST ("{\\0}", "0");
|
|
TEST ("{0\\}", 0);
|
|
|
|
TEST ("{\\{}", "{");
|
|
TEST ("{\\}}", "}");
|
|
|
|
TEST ("a{0}", "a0");
|
|
TEST ("a{0}b", "a0b");
|
|
TEST ("a\\{0\\}b", "a{0}b");
|
|
TEST ("a\\{0,123,4\\}b", "a{0,123,4}b");
|
|
|
|
// extension: bash sequence expansion
|
|
TEST ("{0..a}", "0..a");
|
|
TEST ("{a..0}", "a..0");
|
|
|
|
TEST ("{0..0}", "0");
|
|
TEST ("{0..5}", "0 1 2 3 4 5");
|
|
TEST ("{4..2}", "4 3 2");
|
|
TEST ("{+5..6}", "5 6");
|
|
TEST ("{6..+7}", "6 7");
|
|
TEST ("{+7..+8}", "7 8");
|
|
TEST ("{11..21}", "11 12 13 14 15 16 17 18 19 20 21");
|
|
TEST ("{0001..0002}", "1 2");
|
|
TEST ("{-0001..0002}", "-1 0 1 2");
|
|
|
|
TEST ("{-3..-1}", "-3 -2 -1");
|
|
TEST ("{+3..-2}", "3 2 1 0 -1 -2");
|
|
TEST ("{-3..+2}", "-3 -2 -1 0 1 2");
|
|
|
|
TEST ("{a..g}", "a b c d e f g");
|
|
TEST ("{g..c}", "g f e d c");
|
|
TEST ("{A..G}", "A B C D E F G");
|
|
TEST ("{G..C}", "G F E D C");
|
|
TEST ("{AB..CD}", "AB..CD");
|
|
|
|
TEST ("{0..1}", "0 1");
|
|
TEST ("\\{0..1}", "{0..1}");
|
|
TEST ("{\\0..1}", "0..1");
|
|
TEST ("{0\\..1}", "0..1");
|
|
TEST ("{0.\\.1}", "0..1");
|
|
TEST ("{0..\\1}", "0..1");
|
|
TEST ("{0..1\\}", 0);
|
|
|
|
// list expansion
|
|
TEST ("{,}", "");
|
|
TEST ("{,", 0);
|
|
TEST ("a{,}", "a a");
|
|
TEST ("b{,", 0);
|
|
TEST ("{c,}", "c");
|
|
TEST ("{d,", 0);
|
|
TEST ("{,e}", "e"); // for 100% compatibility this should be " e"
|
|
TEST ("{,f", 0);
|
|
TEST ("{,}g", "g g");
|
|
TEST ("a{,}b", "ab ab");
|
|
|
|
TEST ("{,,}", "");
|
|
TEST ("a{,,}", "a a a");
|
|
TEST ("{b,,}", "b");
|
|
TEST ("{,c,}", "c");
|
|
TEST ("{,,d}", "d");
|
|
TEST ("{,,}e", "e e e");
|
|
TEST ("a{,,}b", "ab ab ab");
|
|
|
|
TEST ("{abc,def}", "abc def");
|
|
TEST ("{ab\\c,d\\ef}", "abc def");
|
|
TEST ("abc{d,e,f}", "abcd abce abcf");
|
|
|
|
TEST ("z{c,a{d..f}a,c}z", "zcz zadaz zaeaz zafaz zcz");
|
|
TEST ("z{c,a{d,e,f}a,c}z", "zcz zadaz zaeaz zafaz zcz");
|
|
|
|
TEST ("{abc,{,d,e,f,}}", "abc d e f");
|
|
TEST ("{abc,{,d,e,f,}}{x,y}", "abcx abcy x y dx dy ex ey fx fy x y");
|
|
TEST ("{abc,{,d\\,e\\,f,}}", "abc d,e,f");
|
|
|
|
// list expansion with embedded whitespace
|
|
TEST ("a{b\\ ,c}", "ab ac");
|
|
TEST ("a{b\\ \\ ,c\\ }", "ab ac ");
|
|
|
|
// series of list and sequence expansions
|
|
TEST ("A{0..3}", "A0 A1 A2 A3");
|
|
TEST ("A{0..2}{6..7}", "A06 A07 A16 A17 A26 A27");
|
|
TEST ("A{A}{0..3}", "AA0 AA1 AA2 AA3");
|
|
TEST ("A{0..3}{A}", "A0A A1A A2A A3A");
|
|
TEST ("{A,a}{I,i}{X,x}", "AIX AIx AiX Aix aIX aIx aiX aix");
|
|
|
|
// list expansion with nested sequence expansions
|
|
TEST ("A{0,{4..7}{,}}", "A0 A4 A4 A5 A5 A6 A6 A7 A7");
|
|
TEST ("a{1,3,x{5..9}y}b", "a1b a3b ax5yb ax6yb ax7yb ax8yb ax9yb");
|
|
|
|
// make absolutely sure that we don't treat ${ as an open brace.
|
|
// we must expand its contents if appropriate.
|
|
TEST ("a${b}c", "a${b}c");
|
|
TEST ("a{${b},c,d}e", "a${b}e ace ade");
|
|
TEST ("a{b,${c},d}e", "abe a${c}e ade");
|
|
TEST ("a{b,${c{1,2}},d}e", "abe a${c1}e a${c2}e ade");
|
|
|
|
// csh specific behavior, lists with single items are valid and
|
|
// expanded
|
|
TEST ("{s}", "s");
|
|
TEST ("{{s}}", "s");
|
|
TEST ("{{{s}}", 0);
|
|
TEST ("{s,t}", "s t");
|
|
TEST ("{{s,t}}", "s t");
|
|
TEST ("{{{{s,t}}}}", "s t");
|
|
|
|
// extension: bash sequence expansion with csh behavior
|
|
TEST ("{{-10..10}}",
|
|
"-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10");
|
|
TEST ("{{{-10..10}}}",
|
|
"-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10");
|
|
|
|
// escaping nested braces
|
|
TEST ("\\{{{-3..3}}", "{-3 {-2 {-1 {0 {1 {2 {3");
|
|
TEST ("{\\{{-3..3}}", "{-3 {-2 {-1 {0 {1 {2 {3");
|
|
TEST ("{{\\{-3..3}}", "{-3..3");
|
|
|
|
TEST ("{{{-3..3\\}}}}", "-3..3}");
|
|
TEST ("{{{-3..3}\\}}}", "-3} -2} -1} 0} 1} 2} 3}");
|
|
TEST ("{{{-3..3}}\\}}", "-3} -2} -1} 0} 1} 2} 3}");
|
|
TEST ("{{{-3..3}}}\\}", "-3} -2} -1} 0} 1} 2} 3}");
|
|
|
|
|
|
// lifted from the bash-3.2 testsuite and modified to be consistent
|
|
// with expectations of the csh shell and our extensions.
|
|
|
|
TEST ("ff{c,b,a}", "ffc ffb ffa");
|
|
TEST ("f{d,e,f}g", "fdg feg ffg");
|
|
TEST ("{l,n,m}xyz", "lxyz nxyz mxyz");
|
|
TEST ("{abc\\,def}", "abc,def");
|
|
TEST ("{abc}", "abc");
|
|
|
|
TEST ("\\{a,b,c,d,e}", "{a,b,c,d,e}");
|
|
TEST ("{x,y,\\{a,b,c}}", "x} y} {a} b} c}");
|
|
TEST ("{x\\,y,\\{abc\\},trie}", "x,y {abc} trie");
|
|
|
|
TEST ("/usr/{ucb/{ex,edit},lib/{ex,how_ex}}",
|
|
"/usr/ucb/ex /usr/ucb/edit /usr/lib/ex /usr/lib/how_ex");
|
|
|
|
TEST ("{}", "");
|
|
TEST ("}", "}");
|
|
TEST ("{", 0);
|
|
|
|
TEST ("abcd{efgh", 0);
|
|
|
|
TEST ("{1..10}", "1 2 3 4 5 6 7 8 9 10");
|
|
|
|
TEST ("{{0..10},braces}", "0 1 2 3 4 5 6 7 8 9 10 braces");
|
|
TEST ("x{{0..10},braces}y",
|
|
"x0y x1y x2y x3y x4y x5y x6y x7y x8y x9y x10y xbracesy");
|
|
|
|
TEST ("{3..3}", "3");
|
|
TEST ("x{3..3}y", "x3y");
|
|
TEST ("{10..1}", "10 9 8 7 6 5 4 3 2 1");
|
|
TEST ("{10..1}y", "10y 9y 8y 7y 6y 5y 4y 3y 2y 1y");
|
|
TEST ("x{10..1}y", "x10y x9y x8y x7y x6y x5y x4y x3y x2y x1y");
|
|
|
|
TEST ("{a..f}", "a b c d e f");
|
|
TEST ("{f..a}", "f e d c b a");
|
|
TEST ("{f..f}", "f");
|
|
|
|
// mixes are incorrectly-formed brace expansions
|
|
TEST ("{1..f}", "1..f");
|
|
TEST ("{f..1}", "f..1");
|
|
|
|
// do negative numbers work?
|
|
TEST ("{-1..-10}", "-1 -2 -3 -4 -5 -6 -7 -8 -9 -10");
|
|
TEST ("{-20..0}",
|
|
"-20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 "
|
|
"-9 -8 -7 -6 -5 -4 -3 -2 -1 0");
|
|
|
|
TEST ("a-{b{d,e}}-c", "a-bd-c a-be-c");
|
|
TEST ("a-{bdef-{g,i}-c", 0);
|
|
}
|
|
|
|
static void
|
|
run_brace_expand_tests ()
|
|
{
|
|
#undef TEST
|
|
#define TEST(s,e) DO_TEST (s,e,rw_brace_expand)
|
|
|
|
TEST_COMMON (rw_brace_expand);
|
|
|
|
// rw_brace_expand does not do whitespace collapse.
|
|
TEST ("a {1,2} b", "a 1 b a 2 b");
|
|
TEST ("a\t\t{1,2}\t\tb", "a\t\t1\t\tb a\t\t2\t\tb");
|
|
|
|
// test whitespace
|
|
TEST (" ", " ");
|
|
TEST (" ", " ");
|
|
TEST (" \t", " \t");
|
|
TEST ("a b", "a b");
|
|
TEST (" a b ", " a b ");
|
|
TEST (" a{b,c}", " ab ac");
|
|
TEST ("a {b,c}", "a b a c");
|
|
TEST ("a{ b,c}", "a b ac");
|
|
TEST ("a{b ,c}", "ab ac");
|
|
TEST ("a{b, c}", "ab a c");
|
|
TEST ("a{b,c }", "ab ac ");
|
|
TEST ("a{b,c} ", "ab ac ");
|
|
|
|
TEST ("{ }", " ");
|
|
TEST ("{{ }}", " ");
|
|
TEST ("{{ }", 0); // brace mismatch
|
|
}
|
|
|
|
static void
|
|
run_shell_expand_tests ()
|
|
{
|
|
#undef TEST
|
|
#define TEST(s,e) DO_TEST (s,e,rw_shell_expand)
|
|
|
|
TEST_COMMON (rw_shell_expand);
|
|
|
|
// rw_shell_expand does whitespace collapse
|
|
TEST ("a {1,2} b", "a 1 2 b");
|
|
TEST ("a\t\t{1,2}\t\tb", "a 1 2 b");
|
|
|
|
// test whitespace
|
|
TEST (" ", "");
|
|
TEST (" ", "");
|
|
TEST (" \t", "");
|
|
TEST ("a b", "a b");
|
|
TEST (" a b ", "a b");
|
|
TEST (" a{b,c}", "ab ac");
|
|
TEST ("a {b,c}", "a b c");
|
|
TEST ("a{ b,c}", 0);
|
|
TEST ("a{b ,c}", 0);
|
|
TEST ("a{b, c}", 0);
|
|
TEST ("a{b,c }", 0);
|
|
TEST ("a{b,c} ", "ab ac");
|
|
|
|
TEST ("{ }", 0); // brace mismatch
|
|
TEST ("{{ }}", 0); // brace mismatch
|
|
TEST ("{{ }", 0); // brace mismatch
|
|
|
|
#if 0 // not implemented yet
|
|
|
|
// set the three variables
|
|
rw_putenv ("var=baz:varx=vx:vary=vy");
|
|
|
|
TEST ("foo{bar,${var}.}", "foobar foobaz.");
|
|
TEST ("foo{bar,${var}}", "foobar foobaz");
|
|
|
|
TEST ("${var}\"{x,y}", "bazx bazy");
|
|
TEST ("$var{x,y}", "vx vy");
|
|
TEST ("${var}{x,y}", "bazx bazy");
|
|
|
|
// unset all three variables
|
|
rw_putenv ("var=:varx=:vary=");
|
|
|
|
#endif // 0
|
|
}
|
|
|
|
int main ()
|
|
{
|
|
run_brace_expand_tests ();
|
|
|
|
run_shell_expand_tests ();
|
|
|
|
// return 0 on success, 1 on failure
|
|
return !(0 == nerrors);
|
|
}
|