Home | History | Annotate | Line # | Download | only in indent
t_errors.sh revision 1.5
      1 #! /bin/sh
      2 # $NetBSD: t_errors.sh,v 1.5 2021/10/24 17:19:49 rillig Exp $
      3 #
      4 # Copyright (c) 2021 The NetBSD Foundation, Inc.
      5 # All rights reserved.
      6 #
      7 # Redistribution and use in source and binary forms, with or without
      8 # modification, are permitted provided that the following conditions
      9 # are met:
     10 # 1. Redistributions of source code must retain the above copyright
     11 #    notice, this list of conditions and the following disclaimer.
     12 # 2. Redistributions in binary form must reproduce the above copyright
     13 #    notice, this list of conditions and the following disclaimer in the
     14 #    documentation and/or other materials provided with the distribution.
     15 #
     16 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26 # POSSIBILITY OF SUCH DAMAGE.
     27 #
     28 # $FreeBSD$
     29 
     30 # Tests for error handling in indent.
     31 
     32 indent=$(atf_config_get usr.bin.indent.test_indent /usr/bin/indent)
     33 nl='
     34 '
     35 
     36 expect_error()
     37 {
     38 	local msg
     39 
     40 	msg="$1"
     41 	shift
     42 
     43 	atf_check -s 'exit:1' \
     44 	    -e "inline:$msg$nl" \
     45 	    "$indent" "$@"
     46 }
     47 
     48 atf_test_case 'option_unknown'
     49 option_unknown_body()
     50 {
     51 	expect_error \
     52 	    'indent: Command line: unknown option "-Z-unknown"' \
     53 	    -Z-unknown
     54 }
     55 
     56 atf_test_case 'option_bool_trailing_garbage'
     57 option_bool_trailing_garbage_body()
     58 {
     59 	expect_error \
     60 	    'indent: Command line: unknown option "-bacchus"' \
     61 	    -bacchus
     62 }
     63 
     64 atf_test_case 'option_int_missing_parameter'
     65 option_int_missing_parameter_body()
     66 {
     67 	expect_error \
     68 	    'indent: Command line: option "-ts" requires an integer parameter' \
     69 	    -tsx
     70 }
     71 
     72 atf_test_case 'option_profile_not_found'
     73 option_profile_not_found_body()
     74 {
     75 	expect_error \
     76 	    'indent: profile ./nonexistent: No such file or directory' \
     77 	    -P./nonexistent
     78 }
     79 
     80 atf_test_case 'option_typedefs_not_found'
     81 option_typedefs_not_found_body()
     82 {
     83 	expect_error \
     84 	    'indent: cannot open file ./nonexistent' \
     85 	    -U./nonexistent
     86 }
     87 
     88 atf_test_case 'option_tabsize_negative'
     89 option_tabsize_negative_body()
     90 {
     91 	expect_error \
     92 	    'indent: Command line: option "-ts" requires an integer parameter' \
     93 	    -ts-1
     94 }
     95 
     96 atf_test_case 'option_tabsize_zero'
     97 option_tabsize_zero_body()
     98 {
     99 	expect_error \
    100 	    'indent: Command line: invalid argument "0" for option "-ts"' \
    101 	    -ts0
    102 }
    103 
    104 atf_test_case 'option_tabsize_large'
    105 option_tabsize_large_body()
    106 {
    107 	# Integer overflow, on both ILP32 and LP64 platforms.
    108 	expect_error \
    109 	    'indent: Command line: invalid argument "81" for option "-ts"' \
    110 	    -ts81
    111 }
    112 
    113 atf_test_case 'option_tabsize_very_large'
    114 option_tabsize_very_large_body()
    115 {
    116 	# Integer overflow, on both ILP32 and LP64 platforms.
    117 	expect_error \
    118 	    'indent: Command line: invalid argument "3000000000" for option "-ts"' \
    119 	    -ts3000000000
    120 }
    121 
    122 atf_test_case 'option_indent_size_zero'
    123 option_indent_size_zero_body()
    124 {
    125 	expect_error \
    126 	    'indent: Command line: invalid argument "0" for option "-i"' \
    127 	    -i0
    128 }
    129 
    130 atf_test_case 'option_int_trailing_garbage'
    131 option_int_trailing_garbage_body()
    132 {
    133 	expect_error \
    134 	    'indent: Command line: invalid argument "3garbage" for option "-i"' \
    135 	    -i3garbage
    136 }
    137 
    138 atf_test_case 'option_buffer_overflow'
    139 option_buffer_overflow_body()
    140 {
    141 	opt='12345678123456781234567812345678'	# 32
    142 	opt="$opt$opt$opt$opt$opt$opt$opt$opt"	# 256
    143 	opt="$opt$opt$opt$opt$opt$opt$opt$opt"	# 2048
    144 	opt="$opt$opt$opt$opt$opt$opt$opt$opt"	# 16384
    145 	printf '%s\n' "-$opt" > indent.pro
    146 
    147 	# TODO: The call to 'diag' should be replaced with 'errx'.
    148 	expect_error \
    149 	    'error: Standard Input:1: buffer overflow in indent.pro, starting with '\''-123456781'\''' \
    150 	    -Pindent.pro
    151 }
    152 
    153 atf_test_case 'option_special_missing_param'
    154 option_special_missing_param_body()
    155 {
    156 	# TODO: Write '-cli' instead of only 'cli'.
    157 	expect_error \
    158 	    'indent: Command line: ``cli'\'\'' requires a parameter' \
    159 	    -cli
    160 
    161 	expect_error \
    162 	    'indent: Command line: ``T'\'\'' requires a parameter' \
    163 	    -T
    164 
    165 	expect_error \
    166 	    'indent: Command line: ``U'\'\'' requires a parameter' \
    167 	    -U
    168 }
    169 
    170 atf_test_case 'unterminated_comment'
    171 unterminated_comment_body()
    172 {
    173 	echo '/*' > comment.c
    174 
    175 	atf_check -s 'exit:1' \
    176 	    -o 'inline:/*'"$nl"' *'"$nl" \
    177 	    -e 'inline:error: Standard Input:2: Unterminated comment'"$nl" \
    178 	    "$indent" -st < comment.c
    179 }
    180 
    181 atf_test_case 'in_place_wrong_backup'
    182 in_place_wrong_backup_body()
    183 {
    184 	cat <<-\EOF > code.c
    185 		int decl;
    186 	EOF
    187 	cp code.c code.c.orig
    188 
    189 	# Due to the strange backup suffix '/subdir', indent tries to create
    190 	# a file named 'code.c/subdir', but 'code.c' is already a regular
    191 	# file, not a directory.
    192 	atf_check -s 'exit:1' \
    193 	    -e 'inline:indent: code.c/subdir: Not a directory'"$nl" \
    194 	    env SIMPLE_BACKUP_SUFFIX="/subdir" "$indent" code.c
    195 
    196 	# Since there was an early error, the original file is kept as is.
    197 	atf_check -o 'file:code.c.orig' \
    198 	    cat code.c
    199 }
    200 
    201 atf_test_case 'argument_input_enoent'
    202 argument_input_enoent_body()
    203 {
    204 	atf_check -s 'exit:1' \
    205 	    -e 'inline:indent: ./nonexistent.c: No such file or directory'"$nl" \
    206 	    "$indent" ./nonexistent.c
    207 }
    208 
    209 atf_test_case 'argument_output_equals_input_name'
    210 argument_output_equals_input_name_body()
    211 {
    212 	echo '/* comment */' > code.c
    213 
    214 	atf_check -s 'exit:1' \
    215 	    -e 'inline:indent: input and output files must be different'"$nl" \
    216 	    "$indent" code.c code.c
    217 }
    218 
    219 atf_test_case 'argument_output_equals_input_file'
    220 argument_output_equals_input_file_body()
    221 {
    222 	echo '/* comment */' > code.c
    223 
    224 	atf_check \
    225 	    "$indent" code.c ./code.c
    226 
    227 	# Oops, the file has become empty since the output is first emptied,
    228 	# before reading any of the input.
    229 	atf_check \
    230 	    cat code.c
    231 }
    232 
    233 atf_test_case 'argument_output_enoent'
    234 argument_output_enoent_body()
    235 {
    236 	expect_error \
    237 	    'indent: subdir/nonexistent.c: No such file or directory' \
    238 	    /dev/null subdir/nonexistent.c
    239 }
    240 
    241 atf_test_case 'argument_too_many'
    242 argument_too_many_body()
    243 {
    244 	echo '/* comment */' > arg1.c
    245 
    246 	expect_error \
    247 	    'indent: unknown parameter: arg3.c' \
    248 	    arg1.c arg2.c arg3.c arg4.c
    249 }
    250 
    251 atf_test_case 'unexpected_end_of_file'
    252 unexpected_end_of_file_body()
    253 {
    254 	echo 'struct{' > code.c
    255 
    256 	expect_error \
    257 	    'error: code.c:1: Stuff missing from end of file' \
    258 	    code.c
    259 
    260 	atf_check \
    261 	    -o 'inline:struct {'"$nl" \
    262 	    cat code.c
    263 }
    264 
    265 atf_test_case 'unexpected_closing_brace_top_level'
    266 unexpected_closing_brace_top_level_body()
    267 {
    268 	echo '}' > code.c
    269 
    270 	expect_error \
    271 	    'error: code.c:1: Statement nesting error' \
    272 	    code.c
    273 	atf_check \
    274 	    -o 'inline:}'"$nl" \
    275 	    cat code.c
    276 }
    277 
    278 atf_test_case 'unexpected_closing_brace_decl'
    279 unexpected_closing_brace_decl_body()
    280 {
    281 	echo 'int i = 3};' > code.c
    282 
    283 	expect_error \
    284 	    'error: code.c:1: Statement nesting error' \
    285 	    code.c
    286 	# Despite the error message, the original file got overwritten with a
    287 	# best-effort rewrite of the code.
    288 	atf_check \
    289 	    -o 'inline:int		i = 3};'"$nl" \
    290 	    cat code.c
    291 }
    292 
    293 atf_test_case 'preprocessing_overflow'
    294 preprocessing_overflow_body()
    295 {
    296 	cat <<-\EOF > code.c
    297 		#if 1
    298 		#if 2
    299 		#if 3
    300 		#if 4
    301 		#if 5
    302 		#if 6
    303 		#endif 6
    304 		#endif 5
    305 		#endif 4
    306 		#endif 3
    307 		#endif 2
    308 		#endif 1
    309 		#endif too much
    310 	EOF
    311 	cat <<-\EOF > stderr.exp
    312 		error: code.c:6: #if stack overflow
    313 		error: code.c:12: Unmatched #endif
    314 		error: code.c:13: Unmatched #endif
    315 	EOF
    316 
    317 	atf_check -s 'exit:1' \
    318 	    -e 'file:stderr.exp' \
    319 	    "$indent" code.c
    320 }
    321 
    322 atf_test_case 'preprocessing_unrecognized'
    323 preprocessing_unrecognized_body()
    324 {
    325 	cat <<-\EOF > code.c
    326 		#unknown
    327 		# 3 "file.c"
    328 		#elif 3
    329 		#else
    330 	EOF
    331 	cat <<-\EOF > stderr.exp
    332 		error: code.c:1: Unrecognized cpp directive
    333 		error: code.c:2: Unrecognized cpp directive
    334 		error: code.c:3: Unmatched #elif
    335 		error: code.c:4: Unmatched #else
    336 	EOF
    337 
    338 	atf_check -s 'exit:1' \
    339 	    -e 'file:stderr.exp' \
    340 	    "$indent" code.c
    341 }
    342 
    343 atf_init_test_cases()
    344 {
    345 	atf_add_test_case 'option_unknown'
    346 	atf_add_test_case 'option_bool_trailing_garbage'
    347 	atf_add_test_case 'option_int_missing_parameter'
    348 	atf_add_test_case 'option_profile_not_found'
    349 	atf_add_test_case 'option_buffer_overflow'
    350 	atf_add_test_case 'option_typedefs_not_found'
    351 	atf_add_test_case 'option_special_missing_param'
    352 	atf_add_test_case 'option_tabsize_negative'
    353 	atf_add_test_case 'option_tabsize_zero'
    354 	atf_add_test_case 'option_tabsize_large'
    355 	atf_add_test_case 'option_tabsize_very_large'
    356 	atf_add_test_case 'option_int_trailing_garbage'
    357 	atf_add_test_case 'option_indent_size_zero'
    358 	atf_add_test_case 'unterminated_comment'
    359 	atf_add_test_case 'in_place_wrong_backup'
    360 	atf_add_test_case 'argument_input_enoent'
    361 	atf_add_test_case 'argument_output_equals_input_name'
    362 	atf_add_test_case 'argument_output_equals_input_file'
    363 	atf_add_test_case 'argument_output_enoent'
    364 	atf_add_test_case 'argument_too_many'
    365 	atf_add_test_case 'unexpected_end_of_file'
    366 	atf_add_test_case 'unexpected_closing_brace_top_level'
    367 	atf_add_test_case 'unexpected_closing_brace_decl'
    368 	atf_add_test_case 'preprocessing_overflow'
    369 	atf_add_test_case 'preprocessing_unrecognized'
    370 }
    371