Fri Aug 18 21:22:30 2017 UTC ()
Add a basic test for $'...' quoting (roughly C ctyle strings).
This test will be skipped on shells (such as /bin/sh in -current as of
the date of this commit) which do not support $'...'

While here fix a typo in a comment (there are probably more...)


(kre)
diff -r1.6 -r1.7 src/tests/bin/sh/t_syntax.sh

cvs diff -r1.6 -r1.7 src/tests/bin/sh/t_syntax.sh (expand / switch to unified diff)

--- src/tests/bin/sh/t_syntax.sh 2017/07/26 17:50:20 1.6
+++ src/tests/bin/sh/t_syntax.sh 2017/08/18 21:22:30 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: t_syntax.sh,v 1.6 2017/07/26 17:50:20 kre Exp $ 1# $NetBSD: t_syntax.sh,v 1.7 2017/08/18 21:22:30 kre Exp $
2# 2#
3# Copyright (c) 2017 The NetBSD Foundation, Inc. 3# Copyright (c) 2017 The NetBSD Foundation, Inc.
4# All rights reserved. 4# All rights reserved.
5# 5#
6# Redistribution and use in source and binary forms, with or without 6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions 7# modification, are permitted provided that the following conditions
8# are met: 8# are met:
9# 1. Redistributions of source code must retain the above copyright 9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer. 10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright 11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the 12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution. 13# documentation and/or other materials provided with the distribution.
14# 14#
@@ -251,27 +251,27 @@ c_line_wrapping_body() { @@ -251,27 +251,27 @@ c_line_wrapping_body() {
251 cat <<- 'DONE' | atf_check -s exit:0 -o inline:"${R}" ${TEST_SH} 251 cat <<- 'DONE' | atf_check -s exit:0 -o inline:"${R}" ${TEST_SH}
252 case $(( $($a && echo 1 || echo 0) + \ 252 case $(( $($a && echo 1 || echo 0) + \
253 $($b && echo 1 || echo 0) + \ 253 $($b && echo 1 || echo 0) + \
254 $($c && echo 1 || echo 0) + \ 254 $($c && echo 1 || echo 0) + \
255 $($d && echo 1 || echo 0) )) 255 $($d && echo 1 || echo 0) ))
256 in 256 in
257 (1) printf OK ;; 257 (1) printf OK ;;
258 (*) printf BAD ;; 258 (*) printf BAD ;;
259 esac 259 esac
260 DONE 260 DONE
261 done 261 done
262 262
263 # inspired by pkgsrc/pkgtools/cwrappers :: libnbcompat/configure 263 # inspired by pkgsrc/pkgtools/cwrappers :: libnbcompat/configure
264 # failure with (broken) sh LINENO core .. avoid recurrence 264 # failure with (broken) sh LINENO code .. avoid recurrence
265 # This test would have failed. 265 # This test would have failed.
266 cat <<- 'DONE' | atf_check -s exit:0 -o inline:'/tmp\n' ${TEST_SH} 266 cat <<- 'DONE' | atf_check -s exit:0 -o inline:'/tmp\n' ${TEST_SH}
267 dn=/tmp/foo 267 dn=/tmp/foo
268 268
269 D=`dirname -- "${dn}" || 269 D=`dirname -- "${dn}" ||
270 expr X"${dn}" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 270 expr X"${dn}" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
271 X"${dn}" : 'X\(//\)[^/]' \| \ 271 X"${dn}" : 'X\(//\)[^/]' \| \
272 X"${dn}" : 'X\(//\)$' \| \ 272 X"${dn}" : 'X\(//\)$' \| \
273 X"${dn}" : 'X\(/\)' \| . 2>/dev/null || 273 X"${dn}" : 'X\(/\)' \| . 2>/dev/null ||
274 echo X"${dn}" | 274 echo X"${dn}" |
275 sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 275 sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
276 s//\1/ 276 s//\1/
277 q 277 q
@@ -285,31 +285,103 @@ c_line_wrapping_body() { @@ -285,31 +285,103 @@ c_line_wrapping_body() {
285 q 285 q
286 }  286 }
287 /^X\(\/\).*/{ 287 /^X\(\/\).*/{
288 s//\1/ 288 s//\1/
289 q 289 q
290 } 290 }
291 s/.*/./; q'` 291 s/.*/./; q'`
292 292
293 echo "${D}" 293 echo "${D}"
294 DONE 294 DONE
295 return 0 295 return 0
296} 296}
297 297
298atf_test_case d_redirects 298atf_test_case d_cstrings
299d_redirects_head() { 299d_cstrings_head() {
 300 atf_set "descr" "Check processing of $' ' quoting (C style strings)"
 301}
 302d_cstrings_body() {
 303 set -xv
 304 unset ENV
 305 if ! ${TEST_SH} -c ": \$'abc'" ||
 306 test $( ${TEST_SH} -c "printf %s \$'abc'" ) != abc
 307 then
 308 atf_skip "\$'...' (C style quoted strings) not supported"
 309 fi
 310
 311 # simple stuff
 312 atf_check -s exit:0 -e empty -o inline:'abc\tdef\n' ${TEST_SH} -c \
 313 "printf '%s\\n' \$'abc\tdef'"
 314 atf_check -s exit:0 -e empty -o inline:'abc\tdef\n' ${TEST_SH} -c \
 315 "printf '%s\\n' \$'abc\011def'"
 316 atf_check -s exit:0 -e empty -o inline:'abc\tdef\n' ${TEST_SH} -c \
 317 "printf '%s\\n' \$'abc\x09'def"
 318 atf_check -s exit:0 -e empty -o inline:'abc$def\n' ${TEST_SH} -c \
 319 "def=xyz; printf '%s\\n' \$'abc\$def'"
 320
 321 # control chars (\c) and unicode \u
 322 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
 323 "test \$'\\1-\\2-\\3' = \$'\\ca-\\cb-\\cc'"
 324 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
 325 "test \$'\\r-\\n-\\f' = \$'\\cm-\\cj-\\cl'"
 326 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
 327 "test \$'\\u0123' = \$'\\304\\243'"
 328 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
 329 "test \$'\\u0123' = \$'\\xC4\\xA3'"
 330 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
 331 "test \$'\\c\\\\' = \$'\\x1C'"
 332 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
 333 "test \$'\\c[\\c]\\c^\\c_\\c?' = \$'\\x1B\\x1D\\x1E\\x1F\\x7F'"
 334
 335 # all the \X sequences for a single char X (ie: not hex/octal/unicode)
 336 atf_check -s exit:0 -e empty -o inline:' \n\r\t \n' \
 337 ${TEST_SH} -c "printf '%s\\n' \$'\\a\\b\\e\\f\\n\\r\\t\\v'"
 338# atf_check -s exit:0 -e empty -o inline:'\7\10\33\14\12\15\11\13' \
 339 atf_check -s exit:0 -e empty -o inline:' \n\r\t \n' \
 340 ${TEST_SH} -c "printf '%s\\n' \$'\\cG\\cH\\x1b\\cl\\cJ\\cm\\cI\\ck'"
 341 atf_check -s exit:0 -e empty -o inline:"'"'"\\\n' \
 342 ${TEST_SH} -c "printf '%s\\n' \$'\\'\\\"\\\\'"
 343
 344 # various invalid $'...' sequences
 345 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 346 ": \$'\\q'"
 347 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 348 ": \$'\\c\\q'"
 349 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 350 ": \$'\\uDEFF'"
 351 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 352 ": \$'\\u00'"
 353 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 354 ": \$'\\u8'"
 355 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 356 ": \$'abcd"
 357 atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
 358 ": \$'abcd\\"
 359
 360 # anything that generates \0 ends the $'...' immediately (\u cannot)
 361 atf_check -s exit:0 -e empty -o inline:'aAa' ${TEST_SH} -c \
 362 "printf '%s' \$'a\\0x'\$'A\\x00X'\$'a\\c@x'"
 363
 364 # \newline in a $'...' is dropped (just like in "" strings)
 365 atf_check -s exit:0 -e empty -o inline:'abcdef' ${TEST_SH} -c \
 366 "printf '%s' \$'abc\\
 367def'"
 368}
 369
 370atf_test_case f_redirects
 371f_redirects_head() {
300 atf_set "descr" "Check parsing of redirect operators" 372 atf_set "descr" "Check parsing of redirect operators"
301} 373}
302d_redirects_body() { 374f_redirects_body() {
303 375
304 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 376 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
305 '>/dev/null' 377 '>/dev/null'
306 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 378 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
307 '</dev/null' 379 '</dev/null'
308 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 380 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
309 '>>/dev/null' 381 '>>/dev/null'
310 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 382 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
311 '<>/dev/null' 383 '<>/dev/null'
312 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 384 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
313 '</dev/null>/dev/null' 385 '</dev/null>/dev/null'
314 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 386 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
315 '>|/dev/null' 387 '>|/dev/null'
@@ -345,31 +417,31 @@ d_redirects_body() { @@ -345,31 +417,31 @@ d_redirects_body() {
345 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 417 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
346 '2>& 1' 418 '2>& 1'
347 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 419 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
348 'FD=1; 2>&"${FD}"' 420 'FD=1; 2>&"${FD}"'
349 atf_check -s exit:0 -o 'inline:hello\n' -e empty ${TEST_SH} -c \ 421 atf_check -s exit:0 -o 'inline:hello\n' -e empty ${TEST_SH} -c \
350 'FD=1; echo hello 2>&"${FD}" >&2' 422 'FD=1; echo hello 2>&"${FD}" >&2'
351 423
352 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 424 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
353 '2>&- 3<&- 4>&-' 425 '2>&- 3<&- 4>&-'
354 426
355 return 0 427 return 0
356} 428}
357 429
358atf_test_case f_variable_syntax 430atf_test_case g_variable_syntax
359f_variable_syntax_head() { 431g_variable_syntax_head() {
360 atf_set "descr" "Check that var names of all legal forms work" 432 atf_set "descr" "Check that var names of all legal forms work"
361} 433}
362f_variable_syntax_body() { 434g_variable_syntax_body() {
363 # don't test _ as a variable, it can be "unusual" 435 # don't test _ as a variable, it can be "unusual"
364 for vname in a ab _a _9 a123 a_1_2_3 __ ___ ____ __1__ _0 \ 436 for vname in a ab _a _9 a123 a_1_2_3 __ ___ ____ __1__ _0 \
365 A AA AAA AaBb _A_a A_a_ a1_ abc_123 ab_12_cd_ef_34_99 \ 437 A AA AAA AaBb _A_a A_a_ a1_ abc_123 ab_12_cd_ef_34_99 \
366 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWXYZ_ \ 438 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWXYZ_ \
367 A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all \ 439 A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all \
368 Then_Make_it_Even_Longer_by_Multiplying_it___A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all \ 440 Then_Make_it_Even_Longer_by_Multiplying_it___A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all \
369 xyzzy __0123454321__ _0_1_2_3_4_5_6_7_8_9_ ABBA X_ Y__ Z___ \ 441 xyzzy __0123454321__ _0_1_2_3_4_5_6_7_8_9_ ABBA X_ Y__ Z___ \
370 _____________________________________________________________ 442 _____________________________________________________________
371 do 443 do
372 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 444 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
373 "unset ${vname}" 445 "unset ${vname}"
374 atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -c \ 446 atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -c \
375 "unset ${vname}; printf %s \${${vname}-OK}" 447 "unset ${vname}; printf %s \${${vname}-OK}"
@@ -443,31 +515,31 @@ f_variable_syntax_body() { @@ -443,31 +515,31 @@ f_variable_syntax_body() {
443 "echo \${${vname}}" 515 "echo \${${vname}}"
444 done 516 done
445 517
446 for vname in ,x -p +h :def 0_1 'x*x' '()' '"' "'" 'a b c' x,y,z '?!' \ 518 for vname in ,x -p +h :def 0_1 'x*x' '()' '"' "'" 'a b c' x,y,z '?!' \
447 ';' a-b a+b 'a?b' 'a:b' 'a%b' 'a#b' 0 1 99 @ '*' '!' '?' 519 ';' a-b a+b 'a?b' 'a:b' 'a%b' 'a#b' 0 1 99 @ '*' '!' '?'
448 do 520 do
449 # failure modes will differ, but they should all fail somehow 521 # failure modes will differ, but they should all fail somehow
450 atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \ 522 atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
451 "${vname}=" 523 "${vname}="
452 done 524 done
453 525
454} 526}
455 527
456atf_test_case g_var_assign 528atf_test_case h_var_assign
457g_var_assign_head() { 529h_var_assign_head() {
458 atf_set "descr" "Check var assignments " 530 atf_set "descr" "Check var assignments "
459} 531}
460g_var_assign_body() { 532h_var_assign_body() {
461 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \ 533 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
462 'a=b' 534 'a=b'
463 atf_check -s not-exit:0 -e not-empty -o empty ${TEST_SH} -c \ 535 atf_check -s not-exit:0 -e not-empty -o empty ${TEST_SH} -c \
464 '\a=b' 536 '\a=b'
465 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \ 537 atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
466 'a=b c=d' 538 'a=b c=d'
467 atf_check -s exit:0 -e empty -o 'inline:e=f\n' ${TEST_SH} -c \ 539 atf_check -s exit:0 -e empty -o 'inline:e=f\n' ${TEST_SH} -c \
468 'a=b c=d echo e=f' 540 'a=b c=d echo e=f'
469 atf_check -s exit:0 -e empty -o 'inline:e=f\n' ${TEST_SH} -c \ 541 atf_check -s exit:0 -e empty -o 'inline:e=f\n' ${TEST_SH} -c \
470 'a=b 2>/dev/null c=d </dev/null echo e=f' 542 'a=b 2>/dev/null c=d </dev/null echo e=f'
471 543
472 # We need to make sure that we do not accidentally 544 # We need to make sure that we do not accidentally
473 # find a command called 'a=b' ... 545 # find a command called 'a=b' ...
@@ -1107,29 +1179,30 @@ z_PR_52426_body() { @@ -1107,29 +1179,30 @@ z_PR_52426_body() {
1107 'case while in while );;(if|then|elif|fi);;(do|done);; esac' 1179 'case while in while );;(if|then|elif|fi);;(do|done);; esac'
1108 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 1180 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
1109 'case until in($);;($$);;($4.50);;(1/2);;0.3333);;esac' 1181 'case until in($);;($$);;($4.50);;(1/2);;0.3333);;esac'
1110 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 1182 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
1111 'case return in !);; !$);; $!);; !#);; (@);; esac' 1183 'case return in !);; !$);; $!);; !#);; (@);; esac'
1112 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \ 1184 atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
1113 'case break in (/);; (\/);; (/\|/\));; (\\//);; esac' 1185 'case break in (/);; (\/);; (/\|/\));; (\\//);; esac'
1114} 1186}
1115 1187
1116atf_init_test_cases() { 1188atf_init_test_cases() {
1117 atf_add_test_case a_basic_tokenisation 1189 atf_add_test_case a_basic_tokenisation
1118 atf_add_test_case b_comments 1190 atf_add_test_case b_comments
1119 atf_add_test_case c_line_wrapping 1191 atf_add_test_case c_line_wrapping
1120 atf_add_test_case d_redirects 1192 atf_add_test_case d_cstrings
1121 atf_add_test_case f_variable_syntax 1193 atf_add_test_case f_redirects
1122 atf_add_test_case g_var_assign 1194 atf_add_test_case g_variable_syntax
 1195 atf_add_test_case h_var_assign
1123 atf_add_test_case i_pipelines 1196 atf_add_test_case i_pipelines
1124 atf_add_test_case j_and_or_lists 1197 atf_add_test_case j_and_or_lists
1125 atf_add_test_case k_lists 1198 atf_add_test_case k_lists
1126 atf_add_test_case l_async_lists 1199 atf_add_test_case l_async_lists
1127 atf_add_test_case m_compound_lists 1200 atf_add_test_case m_compound_lists
1128 atf_add_test_case q_for_loop 1201 atf_add_test_case q_for_loop
1129 atf_add_test_case r_case 1202 atf_add_test_case r_case
1130 atf_add_test_case s_if 1203 atf_add_test_case s_if
1131 atf_add_test_case t_loops 1204 atf_add_test_case t_loops
1132 atf_add_test_case u_case_cont 1205 atf_add_test_case u_case_cont
1133 atf_add_test_case x_functions 1206 atf_add_test_case x_functions
1134 1207
1135 atf_add_test_case z_PR_48498 1208 atf_add_test_case z_PR_48498