Home | History | Annotate | Line # | Download | only in indent
t_errors.sh revision 1.3
      1 #! /bin/sh
      2 # $NetBSD: t_errors.sh,v 1.3 2021/10/14 18:55:41 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: invalid tabsize 0' \
    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: invalid tabsize 81' \
    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: invalid tabsize -1294967296' \
    119 	    -ts3000000000
    120 }
    121 
    122 atf_test_case 'option_indent_size_zero'
    123 option_indent_size_zero_body()
    124 {
    125 	expect_error \
    126 	    'indent: invalid indentation 0' \
    127 	    -i0
    128 }
    129 
    130 atf_test_case 'option_buffer_overflow'
    131 option_buffer_overflow_body()
    132 {
    133 	opt='12345678123456781234567812345678'	# 32
    134 	opt="$opt$opt$opt$opt$opt$opt$opt$opt"	# 256
    135 	opt="$opt$opt$opt$opt$opt$opt$opt$opt"	# 2048
    136 	opt="$opt$opt$opt$opt$opt$opt$opt$opt"	# 16384
    137 	printf '%s\n' "-$opt" > indent.pro
    138 
    139 	# TODO: The call to 'diag' should be replaced with 'errx'.
    140 	expect_error \
    141 	    'Error@1: buffer overflow in indent.pro, starting with '\''-123456781'\''' \
    142 	    -Pindent.pro
    143 }
    144 
    145 atf_test_case 'option_special_missing_param'
    146 option_special_missing_param_body()
    147 {
    148 	# TODO: Write '-cli' instead of only 'cli'.
    149 	expect_error \
    150 	    'indent: Command line: ``cli'\'\'' requires a parameter' \
    151 	    -cli
    152 
    153 	expect_error \
    154 	    'indent: Command line: ``T'\'\'' requires a parameter' \
    155 	    -T
    156 
    157 	expect_error \
    158 	    'indent: Command line: ``U'\'\'' requires a parameter' \
    159 	    -U
    160 }
    161 
    162 atf_test_case 'unterminated_comment'
    163 unterminated_comment_body()
    164 {
    165 	echo '/*' > comment.c
    166 
    167 	atf_check -s 'exit:1' \
    168 	    -o 'inline:/*'"$nl"' *'"$nl" \
    169 	    -e 'inline:/**INDENT** Error@2: Unterminated comment */'"$nl" \
    170 	    "$indent" -st < comment.c
    171 }
    172 
    173 atf_test_case 'in_place_wrong_backup'
    174 in_place_wrong_backup_body()
    175 {
    176 	cat <<-\EOF > code.c
    177 		int decl;
    178 	EOF
    179 	cp code.c code.c.orig
    180 
    181 	# Due to the strange backup suffix '/subdir', indent tries to create
    182 	# a file named 'code.c/subdir', but 'code.c' is already a regular
    183 	# file, not a directory.
    184 	atf_check -s 'exit:1' \
    185 	    -e 'inline:indent: code.c/subdir: Not a directory'"$nl" \
    186 	    env SIMPLE_BACKUP_SUFFIX="/subdir" "$indent" code.c
    187 
    188 	# Since there was an early error, the original file is kept as is.
    189 	atf_check -o 'file:code.c.orig' \
    190 	    cat code.c
    191 }
    192 
    193 atf_test_case 'argument_input_enoent'
    194 argument_input_enoent_body()
    195 {
    196 	atf_check -s 'exit:1' \
    197 	    -e 'inline:indent: ./nonexistent.c: No such file or directory'"$nl" \
    198 	    "$indent" ./nonexistent.c
    199 }
    200 
    201 atf_test_case 'argument_output_equals_input_name'
    202 argument_output_equals_input_name_body()
    203 {
    204 	echo '/* comment */' > code.c
    205 
    206 	atf_check -s 'exit:1' \
    207 	    -e 'inline:indent: input and output files must be different'"$nl" \
    208 	    "$indent" code.c code.c
    209 }
    210 
    211 atf_test_case 'argument_output_equals_input_file'
    212 argument_output_equals_input_file_body()
    213 {
    214 	echo '/* comment */' > code.c
    215 
    216 	atf_check \
    217 	    "$indent" code.c ./code.c
    218 
    219 	# Oops, the file has become empty since the output is first emptied,
    220 	# before reading any of the input.
    221 	atf_check \
    222 	    cat code.c
    223 }
    224 
    225 atf_test_case 'argument_output_enoent'
    226 argument_output_enoent_body()
    227 {
    228 	expect_error \
    229 	    'indent: subdir/nonexistent.c: No such file or directory' \
    230 	    /dev/null subdir/nonexistent.c
    231 }
    232 
    233 atf_test_case 'argument_too_many'
    234 argument_too_many_body()
    235 {
    236 	echo '/* comment */' > arg1.c
    237 
    238 	expect_error \
    239 	    'indent: unknown parameter: arg3.c' \
    240 	    arg1.c arg2.c arg3.c arg4.c
    241 }
    242 
    243 atf_test_case 'unexpected_end_of_file'
    244 unexpected_end_of_file_body()
    245 {
    246 	echo 'struct{' > code.c
    247 
    248 	expect_error \
    249 	    'Error@1: Stuff missing from end of file' \
    250 	    code.c
    251 
    252 	atf_check \
    253 	    -o 'inline:struct {'"$nl" \
    254 	    cat code.c
    255 }
    256 
    257 atf_test_case 'unexpected_closing_brace_top_level'
    258 unexpected_closing_brace_top_level_body()
    259 {
    260 	echo '}' > code.c
    261 
    262 	expect_error \
    263 	    'Error@1: Statement nesting error' \
    264 	    code.c
    265 	atf_check \
    266 	    -o 'inline:}'"$nl" \
    267 	    cat code.c
    268 }
    269 
    270 atf_test_case 'unexpected_closing_brace_decl'
    271 unexpected_closing_brace_decl_body()
    272 {
    273 	echo 'int i = 3};' > code.c
    274 
    275 	expect_error \
    276 	    'Error@1: Statement nesting error' \
    277 	    code.c
    278 	# Despite the error message, the original file got overwritten with a
    279 	# best-effort rewrite of the code.
    280 	atf_check \
    281 	    -o 'inline:int		i = 3};'"$nl" \
    282 	    cat code.c
    283 }
    284 
    285 atf_test_case 'preprocessing_overflow'
    286 preprocessing_overflow_body()
    287 {
    288 	cat <<-\EOF > code.c
    289 		#if 1
    290 		#if 2
    291 		#if 3
    292 		#if 4
    293 		#if 5
    294 		#if 6
    295 		#endif 6
    296 		#endif 5
    297 		#endif 4
    298 		#endif 3
    299 		#endif 2
    300 		#endif 1
    301 		#endif too much
    302 	EOF
    303 	cat <<-\EOF > stderr.exp
    304 		Error@6: #if stack overflow
    305 		Error@12: Unmatched #endif
    306 		Error@13: Unmatched #endif
    307 	EOF
    308 
    309 	atf_check -s 'exit:1' \
    310 	    -e 'file:stderr.exp' \
    311 	    "$indent" code.c
    312 }
    313 
    314 atf_test_case 'preprocessing_unrecognized'
    315 preprocessing_unrecognized_body()
    316 {
    317 	cat <<-\EOF > code.c
    318 		#unknown
    319 		# 3 "file.c"
    320 		#elif 3
    321 		#else
    322 	EOF
    323 	cat <<-\EOF > stderr.exp
    324 		Error@1: Unrecognized cpp directive
    325 		Error@2: Unrecognized cpp directive
    326 		Error@3: Unmatched #elif
    327 		Error@4: Unmatched #else
    328 	EOF
    329 
    330 	atf_check -s 'exit:1' \
    331 	    -e 'file:stderr.exp' \
    332 	    "$indent" code.c
    333 }
    334 
    335 atf_init_test_cases()
    336 {
    337 	atf_add_test_case 'option_unknown'
    338 	atf_add_test_case 'option_bool_trailing_garbage'
    339 	atf_add_test_case 'option_int_missing_parameter'
    340 	atf_add_test_case 'option_profile_not_found'
    341 	atf_add_test_case 'option_buffer_overflow'
    342 	atf_add_test_case 'option_typedefs_not_found'
    343 	atf_add_test_case 'option_special_missing_param'
    344 	atf_add_test_case 'option_tabsize_negative'
    345 	atf_add_test_case 'option_tabsize_zero'
    346 	atf_add_test_case 'option_tabsize_large'
    347 	atf_add_test_case 'option_tabsize_very_large'
    348 	atf_add_test_case 'option_indent_size_zero'
    349 	atf_add_test_case 'unterminated_comment'
    350 	atf_add_test_case 'in_place_wrong_backup'
    351 	atf_add_test_case 'argument_input_enoent'
    352 	atf_add_test_case 'argument_output_equals_input_name'
    353 	atf_add_test_case 'argument_output_equals_input_file'
    354 	atf_add_test_case 'argument_output_enoent'
    355 	atf_add_test_case 'argument_too_many'
    356 	atf_add_test_case 'unexpected_end_of_file'
    357 	atf_add_test_case 'unexpected_closing_brace_top_level'
    358 	atf_add_test_case 'unexpected_closing_brace_decl'
    359 	atf_add_test_case 'preprocessing_overflow'
    360 	atf_add_test_case 'preprocessing_unrecognized'
    361 }
    362