t_misc.sh revision 1.16
1#! /bin/sh 2# $NetBSD: t_misc.sh,v 1.16 2021/11/19 22:24:29 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 indent that do not follow the input-profile-output scheme that is 31# used in t_indent. 32 33indent=$(atf_config_get usr.bin.indent.test_indent /usr/bin/indent) 34nl=' 35' 36 37atf_test_case 'in_place' 38in_place_body() 39{ 40 cat <<-\EOF > code.c 41 int decl; 42 EOF 43 cat <<-\EOF > code.c.exp 44 int decl; 45 EOF 46 cp code.c code.c.orig 47 48 atf_check \ 49 env SIMPLE_BACKUP_SUFFIX=".bak" "$indent" code.c 50 atf_check -o 'file:code.c.exp' \ 51 cat code.c 52 atf_check -o 'file:code.c.orig' \ 53 cat code.c.bak 54} 55 56atf_test_case 'verbose_profile' 57verbose_profile_body() 58{ 59 cat <<-\EOF > .indent.pro 60 -/* comment */bacc 61 -v 62 -fc1 63 EOF 64 cat <<-\EOF > before.c 65 int decl; 66 EOF 67 cat <<-\EOF > after.c.exp 68 int decl; 69 EOF 70 cat <<-\EOF > stdout.exp 71 profile: -fc1 72 profile: -bacc 73 profile: -v 74 profile: -fc1 75 There were 1 output lines and 0 comments 76 (Lines with comments)/(Lines with code): 0.000 77 EOF 78 79 # The code in args.c function set_profile suggests that options from 80 # profile files are echoed to stdout during startup. But since the 81 # command line options are handled after the profile files, a '-v' in 82 # the command line has no effect. That's why '-bacc' is not listed 83 # in stdout, but '-fc1' is. The second round of '-bacc', '-v', '-fc1' 84 # is listed because when running ATF, $HOME equals $PWD. 85 86 atf_check \ 87 -o 'file:stdout.exp' \ 88 "$indent" -v before.c after.c 89 atf_check \ 90 -o 'file:after.c.exp' \ 91 cat after.c 92} 93 94atf_test_case 'nested_struct_declarations' 95nested_struct_declarations_body() 96{ 97 # Trigger the warning about nested struct declarations. 98 99 cat <<-\EOF > code.c 100 struct s01 { struct s02 { struct s03 { struct s04 { 101 struct s05 { struct s06 { struct s07 { struct s08 { 102 struct s09 { struct s10 { struct s11 { struct s12 { 103 struct s13 { struct s14 { struct s15 { struct s16 { 104 struct s17 { struct s18 { struct s19 { struct s20 { 105 struct s21 { struct s22 { struct s23 { struct s24 { 106 };};};}; 107 };};};}; 108 };};};}; 109 };};};}; 110 };};};}; 111 };};};}; 112 EOF 113 cat <<-\EOF > expected.out 114 struct s01 { 115 struct s02 { 116 struct s03 { 117 struct s04 { 118 struct s05 { 119 struct s06 { 120 struct s07 { 121 struct s08 { 122 struct s09 { 123 struct s10 { 124 struct s11 { 125 struct s12 { 126 struct s13 { 127 struct s14 { 128 struct s15 { 129 struct s16 { 130 struct s17 { 131 struct s18 { 132 struct s19 { 133 struct s20 { 134 struct s21 { 135 struct s22 { 136 struct s23 { 137 struct s24 { 138 }; 139 }; 140 }; 141 }; 142 }; 143 }; 144 }; 145 }; 146 }; 147 }; 148 }; 149 }; 150 }; 151 }; 152 }; 153 }; 154 }; 155 }; 156 }; 157 }; 158 }; 159 }; 160 }; 161 }; 162 EOF 163 cat <<-\EOF > expected.err 164 warning: Standard Input:5: Reached internal limit of 20 struct levels 165 warning: Standard Input:6: Reached internal limit of 20 struct levels 166 warning: Standard Input:6: Reached internal limit of 20 struct levels 167 warning: Standard Input:6: Reached internal limit of 20 struct levels 168 warning: Standard Input:6: Reached internal limit of 20 struct levels 169 EOF 170 171 atf_check -o 'file:expected.out' -e 'file:expected.err' \ 172 "$indent" -i1 -nut < 'code.c' 173} 174 175atf_test_case 'option_P_in_profile_file' 176option_P_in_profile_file_body() 177{ 178 # Mentioning another profile via -P has no effect since only a single 179 # profile can be specified on the command line, and there is no 180 # 'include' option. 181 182 # It's syntactically possible to specify a profile file inside another 183 # profile file. Such a profile file is ignored since only a single 184 # profile file is ever loaded. 185 printf '%s\n' '-P/nonexistent' > .indent.pro 186 187 echo 'syntax # error' > code.c 188 189 atf_check -o 'inline:syntax'"$nl"'#error'"$nl" \ 190 "$indent" < code.c 191} 192 193atf_test_case 'option_without_hyphen' 194option_without_hyphen_body() 195{ 196 # TODO: Options in profile files should be required to start with 197 # '-', just like in the command line arguments. 198 199 printf ' -i3 xi5 +di0\n' > .indent.pro 200 201 printf '%s\n' 'int var[] = {' '1,' '}' > code.c 202 printf '%s\n' 'int var[] = {' ' 1,' '}' > code.exp 203 204 atf_check -o 'file:code.exp' \ 205 "$indent" < code.c 206} 207 208atf_test_case 'opt' 209opt_body() 210{ 211 # Test parsing of command line options from a profile file. 212 213 cat <<-\EOF > code.c 214 int global_var; 215 216 int function(int expr) { 217 switch (expr) { case 1: return 1; default: return 0; } 218 } 219 EOF 220 221 cat << \EOF > .indent.pro 222/* The latter of the two options wins. */ 223-di5 224-di12 225 226/* 227 * It is possible to embed comments in the middle of an option, but nobody 228 * does that. 229 */ 230-/* comment */bacc 231-T/* define 232a type */custom_type 233 234/* For int options, trailing garbage would be an error. */ 235-i3 236 237/*For float options, trailing garbage would be an error. */ 238-cli3.5 239 240-b/*/acc /* The comment is '/' '*' '/', making the option '-bacc'. */ 241EOF 242 243 sed '/[$]/d' << \EOF > code.exp 244/* $ The variable name is indented by 12 characters due to -di12. */ 245int global_var; 246 247int 248function(int expr) 249{ 250 switch (expr) { 251/* $ The indentation is 3 + (int)(3.5 * 3), so 3 + 10.5, so 13. */ 252/* $ See parse.c, function parse, 'case switch_expr'. */ 253 case 1: 254/* $ The indentation is 3 + (int)3.5 * 3 + 3, so 3 + 9 + 3, so 15. */ 255/* $ See parse.c, function parse, 'case switch_expr'. */ 256 return 1; 257 default: 258 return 0; 259 } 260} 261EOF 262 263 atf_check -o 'file:code.exp' \ 264 "$indent" code.c -st 265} 266 267atf_test_case 'opt_npro' 268opt_npro_body() 269{ 270 # Mentioning the option -npro in a .pro file has no effect since at 271 # that point, indent has already decided to load the .pro file, and 272 # it only decides once. 273 274 echo ' -npro -di8' > .indent.pro 275 echo 'int var;' > code.c 276 printf 'int\tvar;\n' > code.exp 277 278 atf_check -o 'file:code.exp' \ 279 "$indent" code.c -st 280} 281 282atf_test_case 'opt_U' 283opt_U_body() 284{ 285 # From each line of this file, the first word is taken to be a type 286 # name. 287 # 288 # Since neither '/*' nor '' are syntactically valid type names, this 289 # means that all kinds of comments are effectively ignored. When a 290 # type name is indented by whitespace, it is ignored as well. 291 # 292 # Since only the first word of each line is relevant, any remaining 293 # words can be used for comments. 294 cat <<-\EOF > code.types 295 /* Comments are effectively ignored since they never match. */ 296 # This comment is ignored as well. 297 ; So is this comment. 298 # The following line is empty and adds a type whose name is empty. 299 300 size_t from stddef.h 301 off_t for file offsets 302 ignored_t is ignored since it is indented 303 EOF 304 305 cat <<-\EOF > code.c 306 int known_1 = (size_t) * arg; 307 int known_2 = (off_t) * arg; 308 int ignored = (ignored_t) * arg; 309 EOF 310 cat <<-\EOF > code.exp 311 int known_1 = (size_t)*arg; 312 int known_2 = (off_t)*arg; 313 int ignored = (ignored_t) * arg; 314 EOF 315 316 atf_check -o 'file:code.exp' \ 317 "$indent" -Ucode.types code.c -di0 -st 318} 319 320atf_test_case 'line_no_counting' 321line_no_counting_body() 322{ 323 # Before NetBSD indent.c 1.147 from 2021-10-24, indent reported the 324 # warning in line 2 instead of the correct line 3. 325 326 cat <<-\EOF > code.c 327 void line_no_counting(void) 328 { 329 ()) 330 } 331 EOF 332 333 cat <<-\EOF > code.err 334 warning: code.c:3: Extra ')' 335 EOF 336 337 atf_check -o 'ignore' -e 'file:code.err' \ 338 "$indent" code.c -st 339} 340 341atf_test_case 'default_backup_extension' 342default_backup_extension_body() 343{ 344 echo 'int var;' > code.c 345 echo 'int var;' > code.c.orig 346 347 atf_check \ 348 "$indent" code.c 349 atf_check -o 'file:code.c.orig' \ 350 cat code.c.BAK 351} 352 353atf_test_case 'several_profiles' 354several_profiles_body() 355{ 356 # If the option '-P' occurs several times, only the last of the 357 # profiles is loaded, the others are ignored. 358 359 echo ' --invalid-option' > error.pro 360 echo '' > last.pro 361 echo '' > code.c 362 363 atf_check \ 364 "$indent" -Pnonexistent.pro -Perror.pro -Plast.pro code.c -st 365} 366 367 368atf_test_case 'command_line_vs_profile' 369command_line_vs_profile_body() 370{ 371 # Options from the command line override those from a profile file, 372 # no matter if they appear earlier or later than the '-P' in the 373 # command line. 374 375 echo ' -di24' > custom.pro 376 printf 'int\t\tdecl;\n' > code.c 377 378 atf_check -o 'inline:int decl;\n' \ 379 "$indent" -di0 -Pcustom.pro code.c -st 380 atf_check -o 'inline:int decl;\n' \ 381 "$indent" -Pcustom.pro -di0 code.c -st 382 atf_check -o 'inline:int decl;\n' \ 383 "$indent" -Pcustom.pro code.c -st -di0 384} 385 386atf_init_test_cases() 387{ 388 atf_add_test_case 'in_place' 389 atf_add_test_case 'verbose_profile' 390 atf_add_test_case 'nested_struct_declarations' 391 atf_add_test_case 'option_P_in_profile_file' 392 atf_add_test_case 'option_without_hyphen' 393 atf_add_test_case 'opt' 394 atf_add_test_case 'opt_npro' 395 atf_add_test_case 'opt_U' 396 atf_add_test_case 'line_no_counting' 397 atf_add_test_case 'default_backup_extension' 398 atf_add_test_case 'several_profiles' 399 atf_add_test_case 'command_line_vs_profile' 400} 401