t_misc.sh revision 1.6
1#! /bin/sh 2# $NetBSD: t_misc.sh,v 1.6 2021/10/24 16:46:12 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 /**INDENT** Warning@5: Reached internal limit of 20 struct levels */ 165 /**INDENT** Warning@6: Reached internal limit of 20 struct levels */ 166 /**INDENT** Warning@6: Reached internal limit of 20 struct levels */ 167 /**INDENT** Warning@6: Reached internal limit of 20 struct levels */ 168 /**INDENT** Warning@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 'opt' 194opt_body() 195{ 196 # Test parsing of command line options from a profile file. 197 198 cat <<-\EOF > code.c 199 int global_var; 200 201 int function(int expr) { 202 switch (expr) { case 1: return 1; default: return 0; } 203 } 204 EOF 205 206 cat << \EOF > .indent.pro 207/* The latter of the two options wins. */ 208-di5 209-di12 210 211/* 212 * It is possible to embed comments in the middle of an option, but nobody 213 * does that. 214 */ 215-/* comment */bacc 216-T/* define 217a type */custom_type 218 219/* For int options, trailing garbage would lead to an error message. */ 220-i3 221 222/* 223 * For float options, trailing garbage is ignored. 224 * 225 * See atof. 226 */ 227-cli3.5garbage 228 229-b/*/acc /* The comment is '/' '*' '/', making the option '-bacc'. */ 230EOF 231 232 sed '/[$]/d' << \EOF > code.exp 233/* $ The variable name is indented by 12 characters due to -di12. */ 234int global_var; 235 236int 237function(int expr) 238{ 239 switch (expr) { 240/* $ The indentation is 3 + (int)(3.5 * 3), so 3 + 10.5, so 13. */ 241/* $ See parse.c, function parse, 'case switch_expr'. */ 242 case 1: 243/* $ The indentation is 3 + (int)3.5 * 3 + 3, so 3 + 9 + 3, so 15. */ 244/* $ See parse.c, function parse, 'case switch_expr'. */ 245 return 1; 246 default: 247 return 0; 248 } 249} 250EOF 251 252 atf_check -o 'file:code.exp' \ 253 "$indent" code.c -st 254} 255 256atf_test_case 'opt_npro' 257opt_npro_body() 258{ 259 # Mentioning the option -npro in a .pro file has no effect since at 260 # that point, indent has already decided to load the .pro file, and 261 # it only decides once. 262 263 echo ' -npro -di8' > .indent.pro 264 echo 'int var;' > code.c 265 printf 'int\tvar;\n' > code.exp 266 267 atf_check -o 'file:code.exp' \ 268 "$indent" code.c -st 269} 270 271atf_test_case 'opt_U' 272opt_U_body() 273{ 274 # From each line of this file, the first word is taken to be a type 275 # name. 276 # 277 # Since neither '/*' nor '' are syntactically valid type names, this 278 # means that all kinds of comments are effectively ignored. When a 279 # type name is indented by whitespace, it is ignored as well. 280 # 281 # Since only the first word of each line is relevant, any remaining 282 # words can be used for comments. 283 cat <<-\EOF > code.types 284 /* Comments are effectively ignored since they never match. */ 285 # This comment is ignored as well. 286 ; So is this comment. 287 # The following line is empty and adds a type whose name is empty. 288 289 size_t from stddef.h 290 off_t for file offsets 291 ignored_t is ignored since it is indented 292 EOF 293 294 cat <<-\EOF > code.c 295 int known_1 = (size_t) * arg; 296 int known_2 = (off_t) * arg; 297 int ignored = (ignored_t) * arg; 298 EOF 299 cat <<-\EOF > code.exp 300 int known_1 = (size_t)*arg; 301 int known_2 = (off_t)*arg; 302 int ignored = (ignored_t) * arg; 303 EOF 304 305 atf_check -o 'file:code.exp' \ 306 "$indent" -Ucode.types code.c -di0 -st 307} 308 309atf_test_case 'line_no_counting' 310line_no_counting_body() 311{ 312 cat <<-\EOF > code.c 313 void line_no_counting(void) 314 { 315 ()) 316 } 317 EOF 318 319 # FIXME: the wrong ')' is in line 3, not 2. 320 cat <<-\EOF > code.err 321 /**INDENT** Warning@2: Extra ) */ 322 EOF 323 324 atf_check -o 'ignore' -e 'file:code.err' \ 325 "$indent" code.c -st 326} 327 328atf_init_test_cases() 329{ 330 atf_add_test_case 'in_place' 331 atf_add_test_case 'verbose_profile' 332 atf_add_test_case 'nested_struct_declarations' 333 atf_add_test_case 'option_P_in_profile_file' 334 atf_add_test_case 'opt' 335 atf_add_test_case 'opt_npro' 336 atf_add_test_case 'opt_U' 337 atf_add_test_case 'line_no_counting' 338} 339