#!/lib/initcpio/busybox ash . ./init_functions failed=0 tests=0 e_ok=0 e_parser_failure=2 e_assertion_failure=130 assert() { local expect_fail= key= expected_value= actual_value if [ "$1" = '--expect-fail' ]; then expect_fail=y shift fi key=$1 expected_value=$2 eval actual_value=\$"$1" case $actual_value in $expected_value) if [ -n "$expect_fail" ]; then echo "EXPECTED FAIL: $key: expected='$expected_value', got='$actual_value'" return 1 fi ;; *) if [ -z "$expect_fail" ]; then echo "FAIL: $key: expected='$expected_value', got='$actual_value'" return 1 fi ;; esac return 0 } test_parse() { local flag= cmdline= expect_fail= expect_parse_fail= tests=$(( tests + 1 )) for flag; do case $flag in --expect-fail) expect_fail='--expect-fail' shift ;; --expect-parse-fail) expect_parse_fail=y shift ;; *) break ;; esac done cmdline=$1; shift [ -n "$V" ] && echo "testing cmdline: $cmdline" echo "$cmdline" | { parse_cmdline result=0 while [ "$#" -gt 0 ]; do key=$1 expected_value=$2 shift 2 assert $expect_fail "$key" "$expected_value" || result=$e_assertion_failure done exit "$result" } 2>/dev/null case $? in $e_parser_failure) # parser failure if [ -z "$expect_parse_fail" ]; then echo "FAIL: parse_cmdline failed" failed=$(( failed + 1 )) fi ;; $e_assertion_failure) # test assertion failure failed=$(( failed + 1 )) ;; $e_ok) if [ -n "$expect_parse_fail" ]; then echo "EXPECTED_FAIL: parse_cmdline succeeded" failed=$(( failed + 1 )) fi ;; esac } # bare words test_parse 'foo' \ 'foo' 'y' test_parse 'foo bar' \ 'foo' 'y' \ 'bar' 'y' # overwriting test_parse 'foo=bar bar=baz foo bar="no pe"' \ 'bar' 'no pe' \ 'foo' 'y' # simple key=value assignment test_parse 'foo=bar' \ 'foo' 'bar' test_parse 'foo=bar bar=baz' \ 'foo' 'bar' \ 'bar' 'baz' test_parse '_derpy=hooves' \ '_derpy' 'hooves' test_parse 'f5=abc f_5_=abc' \ 'f5' 'abc' \ 'f_5_' 'abc' test_parse 'v="foo bar=baz"' \ 'v' 'foo bar=baz' # double quoting test_parse 'foo="bar"' \ 'foo' 'bar' test_parse 'foo="bar baz"' \ 'foo' 'bar baz' # single quoting test_parse "foo='bar'" \ 'foo' 'bar' test_parse "foo='bar baz'" \ 'foo' 'bar baz' # dangling quotes test_parse 'foo="bar' \ 'foo' '"bar' test_parse 'foo=bar"' \ 'foo' 'bar"' # nested quotes test_parse "foo='\"bar baz\"' herp='\"de\"rp'" \ 'foo' '"bar baz"' \ 'herp' '"de"rp' # escaped quotes test_parse 'foo=bar"baz' \ 'foo' 'bar"baz' # neighboring quoted regions test_parse --expect-fail 'foo="bar""baz"' \ 'foo' 'barbaz' test_parse --expect-fail "foo=\"bar\"'baz'" \ 'foo' "barbaz" test_parse --expect-fail "foo='bar'\"baz\"" \ 'foo' "barbaz" # comments test_parse 'foo=bar # ignored content' \ 'foo' 'bar' \ 'ignored' '' \ 'content' '' test_parse 'foo=bar #ignored content' \ 'foo' 'bar' \ 'ignored' '' \ 'content' '' test_parse 'foo="bar #baz" parse=this' \ 'foo' 'bar #baz' \ 'parse' 'this' # shell metachars test_parse 'foo=*' \ 'foo' '\*' test_parse 'Make*' \ 'Makefile' '' test_parse '[Makefile]*' \ 'Makefile' '' \ 'init' '' \ 'functions' '' # invalid names test_parse 'in-valid=name' test_parse '6foo=bar' test_parse '"gar bage"' \ 'gar' '' \ 'bage' '' # special handling test_parse 'rw' \ 'ro' '' \ 'rw' '' \ 'rwopt' 'rw' test_parse 'ro' \ 'ro' '' \ 'rw' '' \ 'rwopt' 'ro' test_parse 'fstype=btrfs' \ 'rootfstype' 'btrfs' test_parse 'fsck.mode=force' \ 'forcefsck' 'y' \ 'fastboot' '' test_parse 'fsck.mode=skip' \ 'forcefsck' '' \ 'fastboot' 'y' test_parse 'rd.debug' \ 'rd_debug' 'y' test_parse 'rd.log' \ 'rd_logmask' '6' test_parse 'rd.log=all' \ 'rd_logmask' '7' test_parse 'rd.log=console' \ 'rd_logmask' '4' test_parse 'rd.log=kmsg' \ 'rd_logmask' '2' test_parse 'rd.log=file' \ 'rd_logmask' '1' # a mix of stuff test_parse 'foo=bar bareword bar="ba az"' \ 'foo' 'bar' \ 'bareword' 'y' \ 'bar' 'ba az' if [ "$failed" -eq 0 ]; then echo "PASS: ${0##*/test_} ($tests tests)" exit 0 else echo "FAIL: $failed tests failed" exit 1 fi