412 lines
14 KiB
Bash
Executable File
412 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# We have many special echo statements with carefully planned good and bad
|
|
# escapes that are flagged. This directive disables the message and applies to
|
|
# the entire script.
|
|
# shellcheck disable=2028
|
|
true
|
|
|
|
INIVALUE=inivalue
|
|
[ -x ./inivalue ] && INIVALUE=./inivalue
|
|
|
|
command -v "$INIVALUE" > /dev/null 2>&1 || { r "*** Missing inivalue executable"; exit 1; }
|
|
|
|
r() { echo "$@" >> result; }
|
|
f() { echo "***" "$@" "failed" >> result; }
|
|
t() { echo "***" "$@" "did not fail" >> result; }
|
|
tst() { "$INIVALUE" "$@" xtest.ini >> result 2>&1; }
|
|
|
|
true > result
|
|
r "+++ Running test program for 'inivalue' +++"
|
|
|
|
r "--- test ini-file does not exist"
|
|
"$INIVALUE" --var=dontcare this_file_does_not_exist_and_will_never_be_here.ini >> result 2>&1 && t "Missing ini-file"
|
|
|
|
r "--- test missing include filename (without blank)"
|
|
echo "#INCLUDE" > xtest.ini
|
|
tst --var=dontcare && t "Missing include"
|
|
|
|
r "--- test missing include filename (with blank)"
|
|
echo "#INCLUDE " > xtest.ini
|
|
tst --var=dontcare && t "Missing include"
|
|
|
|
r "--- test include file not found"
|
|
echo "#INCLUDE this_file_does_not_exist.inc" > xtest.ini
|
|
tst --var=dontcare && t "Nonexistent include file"
|
|
|
|
r "--- test include file recursion"
|
|
echo "#INCLUDE xtest.inc" > xtest.ini
|
|
echo "#INCLUDE xtest.ini" > xtest.inc
|
|
tst --var=dontcare && t "Include recursion"
|
|
# we /could/ test max include depth, but that is a pain...
|
|
|
|
r "--- test invalid section, missing ']'"
|
|
echo "[SECTION" > xtest.ini
|
|
tst --var=VAR && t "Invalid section"
|
|
|
|
r "--- test invalid section, no content"
|
|
echo "[]" > xtest.ini
|
|
tst --var=VAR && t "Invalid section"
|
|
echo "[ ]" > xtest.ini
|
|
tst --var=VAR && t "Invalid section"
|
|
|
|
r "--- test invalid section, invalid identifier"
|
|
echo "[0SECTION]" > xtest.ini
|
|
tst --var=VAR && t "Invalid section"
|
|
echo "[xæøåz]" > xtest.ini
|
|
tst --var=VAR && t "Invalid section"
|
|
|
|
r "--- test duplicate section merge warning"
|
|
( echo "[SECTION]"
|
|
echo "[SECTION]"
|
|
echo "VAR=val" ) > xtest.ini
|
|
tst --var=VAR || f "Merging duplicate section"
|
|
|
|
r "--- test section trailing junk warning"
|
|
( echo "[SECTION] This is junk"
|
|
echo "VAR=val" ) > xtest.ini
|
|
tst --var=VAR || f "Trailing section junk"
|
|
|
|
r "--- test invalid variable name missing '='"
|
|
( echo "[SECTION]"
|
|
echo "VAR" ) > xtest.ini
|
|
tst --var=VAR && t "Invalid variable missing '='"
|
|
|
|
r "--- test invalid variable name missing identifier"
|
|
( echo "[SECTION]"
|
|
echo " = value" ) > xtest.ini
|
|
tst --var=VAR && t "Invalid variable missing identifier"
|
|
|
|
r "--- test invalid variable name missing '='"
|
|
( echo "[SECTION]"
|
|
echo "VAR x" ) > xtest.ini
|
|
tst --var=VAR && t "Invalid variable missing '='"
|
|
|
|
r "--- test invalid variable name identifier"
|
|
( echo "[SECTION]"
|
|
echo "0VAR=val" ) > xtest.ini
|
|
tst --var=0VAR && t "Invalid variable name"
|
|
( echo "[SECTION]"
|
|
echo "VÅR=val" ) > xtest.ini
|
|
tst --var=VAR && t "Invalid variable name"
|
|
( echo "[SECTION]"
|
|
echo "VAR x=val" ) > xtest.ini
|
|
tst --var=VAR && t "Invalid variable name"
|
|
|
|
|
|
r "--- test invalid variable outside section"
|
|
echo "VAR=val" > xtest.ini
|
|
tst --var=VAR && t "Invalid variable outside section"
|
|
|
|
r "--- test continuation"
|
|
( echo "[SECTION]"
|
|
echo "VAR=val \\"
|
|
echo " more val" ) > xtest.ini
|
|
tst --var=VAR || f "Variable/line continuation"
|
|
|
|
r "--- test last line has continuation without newline"
|
|
( echo "[SECTION]"
|
|
echo -n "VAR=val \\" ) > xtest.ini
|
|
tst --var=VAR && t "Variable/line continuation"
|
|
|
|
r "--- test last line has continuation with newline"
|
|
( echo "[SECTION]"
|
|
echo "VAR=val \\" ) > xtest.ini
|
|
tst --var=VAR && t "Variable/line continuation"
|
|
|
|
r "--- test getting all sections"
|
|
( echo "[S1]"
|
|
echo "VAR=s1"
|
|
echo "[S2]"
|
|
echo "VAR=s2a"
|
|
echo "VAR=s2b"
|
|
echo "VAR=s2c"
|
|
echo "[S3]"
|
|
echo "VAR=s3" ) > xtest.ini
|
|
tst --sections || f "Getting sections"
|
|
|
|
r "--- test get all variable of a name"
|
|
tst --var=VAR --all || f "Getting [*]VAR[1,-]"
|
|
r "--- test get all variable of a name from the 3'rd"
|
|
tst --var=VAR --all --num=3 || f "Getting [*]VAR[3,-]"
|
|
r "--- test get all variable of a name from unexisting number"
|
|
tst --var=VAR --all --num=42 && t "Getting [*]VAR[42,-]"
|
|
|
|
r "--- test get the 2'nd variable of global name VAR"
|
|
tst --var=VAR --num=2 || f "Getting [*]VAR[2]"
|
|
r "--- test get the 2'nd variable of name VAR in section"
|
|
tst --var=VAR --num=2 --sec=S2 || f "Getting [S2]VAR[2]"
|
|
r "--- test get the unexisting number variable of name VAR in section"
|
|
tst --var=VAR --num=42 --sec=S2 && t "Getting [S2]VAR[42]"
|
|
|
|
( echo "[SECTION]"
|
|
echo "VARdp=42"
|
|
echo "VARxp=0x2a"
|
|
echo "VARop=0o52"
|
|
echo "VARbp=0b101010"
|
|
echo "VARdm=-42"
|
|
echo "VARxm=-0x2a"
|
|
echo "VARom=-0o52"
|
|
echo "VARbm=-0b101010"
|
|
echo "VARrp=+4.2e1"
|
|
echo "VARrm=-4.2e1"
|
|
echo "VARBadBool=BadBool"
|
|
echo "VARBadNum=BadInt42"
|
|
echo "VARWarnNum=42Warn"
|
|
echo "VARBt1=TRUE"
|
|
echo "VARBt2=true"
|
|
echo "VARBt3=True"
|
|
echo "VARBt4=yes"
|
|
echo "VARBt5=YeS"
|
|
echo "VARBt6=1"
|
|
echo "VARBt7=oN"
|
|
echo "VARBf1=FALSE"
|
|
echo "VARBf2=false"
|
|
echo "VARBf3=FalSe"
|
|
echo "VARBf4=no"
|
|
echo "VARBf5=nO"
|
|
echo "VARBf6=0"
|
|
echo "VARBf7=oFf" ) > xtest.ini
|
|
r "--- test integer/unsigned value"
|
|
for i in d x o b; do
|
|
tst --var="VAR${i}p" --type=i || f "Integer VAR${i}p variable"
|
|
tst --var="VAR${i}m" --type=i || f "Integer VAR${i}m variable"
|
|
tst --var="VAR${i}p" --type=u || f "Unsigned VAR${i}p variable"
|
|
tst --var="VAR${i}m" --type=u || f "Unsigned VAR${i}m variable"
|
|
done
|
|
r "--- test real value"
|
|
tst --var=VARrp --type=r || f "Real variable"
|
|
tst --var=VARrm --type=r || f "Real variable"
|
|
r "--- test boolean value"
|
|
for i in 1 2 3 4 5 6 7; do
|
|
tst --var="VARBt${i}" --type=b || f "Boolean variable VARBt${i}"
|
|
tst --var="VARBf${i}" --type=b || f "Boolean variable VARBf${i}"
|
|
tst --var="VARBt${i}" --type=b -b || f "Boolean variable VARBt${i}"
|
|
tst --var="VARBf${i}" --type=b -b || f "Boolean variable VARBf${i}"
|
|
tst --var="VARBt${i}" --type=b -B || f "Boolean variable VARBt${i}"
|
|
tst --var="VARBf${i}" --type=b -B || f "Boolean variable VARBf${i}"
|
|
done
|
|
|
|
r "--- test bad integer/unsigned value"
|
|
tst --var="VARBadNum" --type=i && t "Bad integer VARBadNum"
|
|
tst --var="VARBadNum" --type=u && t "Bad unsigned VARBadNum"
|
|
tst --var="VARBadNum" --type=r && t "Bad real VARBadNum"
|
|
r "--- test warn integer/unsigned trailing context"
|
|
tst --var="VARWarnNum" --type=i || f "Bad integer VARWarnNum"
|
|
tst --var="VARWarnNum" --type=u || f "Bad unsigned VARWarnNum"
|
|
tst --var="VARWarnNum" --type=r || f "Bad real VARWarnNum"
|
|
r "--- test bad boolean value"
|
|
tst --var="VARBadBool" --type=b && t "Bad boolean VARBadBool"
|
|
|
|
r "--- test bad range"
|
|
tst --var=VARdm --type=i -m 0 -M -1 && t "Integer range"
|
|
tst --var=VARdm --type=u -m 1 -M 0 && t "Integer range"
|
|
tst --var=VARdm --type=r -m 0 -M -1 && t "Integer range"
|
|
|
|
r "--- test range tested value"
|
|
tst --var=VARdm --type=i -m -1 -M 0 && t "Integer range"
|
|
tst --var=VARdm --type=i -m -50 -M -40 || f "Integer range"
|
|
tst --var=VARdm --type=u -m 0 -M -0 && t "Unsigned range"
|
|
tst --var=VARdp --type=u -m 42 -M 42 || f "Unsigned range"
|
|
tst --var=VARdm --type=u -m -50 -M -40 || f "Unsigned range"
|
|
tst --var=VARrp --type=r -m 8.0 -M 9.999 && t "Real range"
|
|
tst --var=VARrp --type=r -m 3.14 -M 45.0 || f "Real range"
|
|
tst --var=VARrm --type=r -m -1.21 -M 0.0 && t "Real range"
|
|
tst --var=VARrm --type=r -m -50.1 -M -40 || f "Real range"
|
|
|
|
r "--- test tilde expansion without HOME"
|
|
XHOME="$HOME"
|
|
export -n HOME
|
|
( echo "[SECTION]"
|
|
echo "VAR=~/xyz" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION --tildeexpand && t "Missing HOME"
|
|
|
|
r "--- test tilde expansion with HOME"
|
|
HOME="/we/control/home"
|
|
export HOME
|
|
tst --var=VAR --sec=SECTION --tildeexpand || f "Using HOME"
|
|
HOME="$XHOME"
|
|
export HOME
|
|
unset XHOME
|
|
|
|
r "--- reproduce ini-file content"
|
|
( echo "[QUINE]"
|
|
echo "VAR=42"
|
|
echo "VAR=0x2a"
|
|
echo "VAR=0o52"
|
|
echo "VAR=0b101010"
|
|
echo "[QUOTED]"
|
|
echo "S='\"single surrounding \\\\ double\"'"
|
|
echo "D=\"'double surrounding \\\\ single'\""
|
|
echo "E=embedded \"double\" and 'single'"
|
|
echo "C=\" spaces and \\x1f newline\\n\""
|
|
echo "U=\\x20 start spaces"
|
|
echo "V=end spaces \\x20"
|
|
echo "W=\\x20 all spaces \\x20"
|
|
echo "[NOTQUINE]"
|
|
echo "This=-42"
|
|
echo "iS=-0x2a"
|
|
echo "a=-0o52"
|
|
echo "sTrAnGe=-0b101010"
|
|
echo "Variable=Variable" ) > xtest.ini
|
|
true > quine.ini
|
|
for s in $("$INIVALUE" --sections xtest.ini); do
|
|
echo "[$s]" >> quine.ini
|
|
"$INIVALUE" --variables --content --sec "$s" xtest.ini >> quine.ini
|
|
done
|
|
if diff -u xtest.ini quine.ini >> result 2>&1; then
|
|
r "ini-file reproduction success"
|
|
else
|
|
f "quine diff"
|
|
fi
|
|
|
|
r "--- comment removal processing"
|
|
( echo " ; comment ignored"
|
|
echo " # comment ignored"
|
|
echo "[MUSTFAILHERE" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Must fail @line 3"
|
|
( echo " [SECTION] ; comment ignored"
|
|
echo " VARa=blabla # comment not ignored"
|
|
echo " VARb=blabla ; comment not ignored"
|
|
) > xtest.ini
|
|
tst --var=VARa --sec=SECTION || f "Comment VARa removal"
|
|
tst --var=VARb --sec=SECTION || f "Comment VARb removal"
|
|
|
|
r "--- string processing single/double quote"
|
|
( echo "[SECTION]"
|
|
echo "VARs='foo'"
|
|
echo "VARq=\"bar\"" ) > xtest.ini
|
|
tst --var=VARs --sec=SECTION || f "Single quote string"
|
|
tst --var=VARq --sec=SECTION || f "Double quote string"
|
|
|
|
r "--- string processing single/double in normal text"
|
|
( echo "[SECTION]"
|
|
echo "VARs=foo 'quote' bar"
|
|
echo "VARq=bar \"quote\" foo" ) > xtest.ini
|
|
tst --var=VARs --sec=SECTION || f "Embedded single quote string"
|
|
tst --var=VARq --sec=SECTION || f "Embedded double quote string"
|
|
|
|
r "--- string continuations escaped newlines"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\"some\n \\"
|
|
echo " string\n \\"
|
|
echo " separated on\n \\"
|
|
echo " lines\"" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION || f "String collection and continuation"
|
|
|
|
r "--- embedded nul in values"
|
|
( echo "[SECTION]"
|
|
echo -e "VAR=val\0val" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Embedded NUL in value"
|
|
( echo "[SECTION]"
|
|
echo -e "VAR=val\0val" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Embedded literal NUL"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\0" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Embedded octal NUL"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\x00" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Embedded hex NUL"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\u0000" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Embedded UTF-16 NUL"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\U00000000" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Embedded UTF-32 NUL"
|
|
|
|
r "--- escape invalid and improper hex"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\xYZ" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid hex escape"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\xY" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Improper short hex escape"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\"\\xY \"" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid short hex escape"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\uVWZY" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid hex UTF-16"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\uVWZ" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Improper short hex UTF-16"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\"\\uVWZ \"" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid short hex UTF-16"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\Uvwxyijkl" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid hex UTF-32"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\Uvwxyijk" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Improper short hex UTF-32"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\"\\Uvwxyijk \"" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid short hex UTF-32"
|
|
|
|
r "--- UTF-16 surrogates, sigh"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\ud800" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Missing UTF-16 low surrogate"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\udc00" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-16 high surrogate"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\ud800\\ud800" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-16 low surrogate"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\"\\ud800\\udc0 \"" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-16 low surrogate"
|
|
( echo "[SECTION]"
|
|
# f600; smiley
|
|
echo "VAR=\\ud83d\\ude00" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION || f "Valid UTF-16"
|
|
|
|
r "--- invalid code points"
|
|
( echo "[SECTION]"
|
|
echo "VAR=\\U00110000" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid code point UTF-32"
|
|
|
|
r "--- valid code points"
|
|
( echo "[SECTION]"
|
|
# AAAA
|
|
echo "VAR=\\101\\x41\\u0041\\U00000041" ) > xtest.ini
|
|
tst --var=VAR --sec=SECTION || f "Valid code points"
|
|
|
|
r "--- invalid UTF-8"
|
|
echo -e '[SECTION]\nVAR="\\xc0 "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 c0 overlap"
|
|
echo -e '[SECTION]\nVAR="\\xc1 "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 c1 overlap"
|
|
echo -e '[SECTION]\nVAR="\\xc2"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 c2 short seq"
|
|
echo -e '[SECTION]\nVAR="\\xe0\\x8f"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 e08f overlap"
|
|
echo -e '[SECTION]\nVAR="\\xed\\xa0"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 surrogate"
|
|
echo -e '[SECTION]\nVAR="\\xed\\x9f"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 ed9f short seq"
|
|
echo -e '[SECTION]\nVAR="\\xf0\\x8f"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f08f overlap"
|
|
echo -e '[SECTION]\nVAR="\\xf0\\x90\\x80"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f09080 short seq"
|
|
echo -e '[SECTION]\nVAR="\\xf4\\x90"' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f490 code point"
|
|
echo -e '[SECTION]\nVAR="\\xf5 "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f5 code point"
|
|
echo -e '[SECTION]\nVAR="\\xf6 "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f6 code point"
|
|
echo -e '[SECTION]\nVAR="\\xf7 "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f7 code point"
|
|
echo -e '[SECTION]\nVAR="\\xf8 "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 f8 code point"
|
|
echo -e '[SECTION]\nVAR="\\xff "' > xtest.ini
|
|
tst --var=VAR --sec=SECTION && t "Invalid UTF-8 ff code point"
|
|
# f600; smiley: 11110 000 10 011111 10 011000 10 000000
|
|
echo -e '[SECTION]\nVAR=\\xf0\\x9f\\x98\\x80' > xtest.ini
|
|
tst --var=VAR --sec=SECTION || f "UTF-8 Smiley"
|
|
|
|
r "+++ all done +++"
|
|
|
|
rm -f xtest.ini xtest.inc quine.ini
|
|
# vim: ts=4 sw=4
|