indent: clean up the code, add a few testsdiff -r1.7 -r1.8 src/tests/usr.bin/indent/fmt_block.c
(rillig)
--- src/tests/usr.bin/indent/fmt_block.c 2023/05/22 23:03:16 1.7
+++ src/tests/usr.bin/indent/fmt_block.c 2023/06/14 20:46:08 1.8
@@ -1,22 +1,21 @@ | @@ -1,22 +1,21 @@ | |||
1 | /* $NetBSD: fmt_block.c,v 1.7 2023/05/22 23:03:16 rillig Exp $ */ | 1 | /* $NetBSD: fmt_block.c,v 1.8 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Tests for formatting blocks of statements and declarations. | 4 | * Tests for formatting blocks of statements and declarations. | |
5 | * | 5 | * | |
6 | * See also: | 6 | * See also: | |
7 | * lsym_lbrace.c | 7 | * lsym_lbrace.c | |
8 | * psym_stmt.c | 8 | * psym_stmt.c | |
9 | * psym_stmt_list.c | |||
10 | */ | 9 | */ | |
11 | 10 | |||
12 | //indent input | 11 | //indent input | |
13 | void | 12 | void | |
14 | function(void) | 13 | function(void) | |
15 | { | 14 | { | |
16 | if (true) { | 15 | if (true) { | |
17 | 16 | |||
18 | } | 17 | } | |
19 | 18 | |||
20 | { | 19 | { | |
21 | print("block"); | 20 | print("block"); | |
22 | } | 21 | } |
--- src/tests/usr.bin/indent/ps_ind_level.c 2023/05/15 14:55:47 1.7
+++ src/tests/usr.bin/indent/ps_ind_level.c 2023/06/14 20:46:08 1.8
@@ -1,41 +1,50 @@ | @@ -1,41 +1,50 @@ | |||
1 | /* $NetBSD: ps_ind_level.c,v 1.7 2023/05/15 14:55:47 rillig Exp $ */ | 1 | /* $NetBSD: ps_ind_level.c,v 1.8 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * The indentation of the very first line of a file determines the | 4 | * The indentation of the very first line of a file determines the | |
5 | * indentation of the remaining code. Even if later code has a smaller | 5 | * indentation of the remaining code. This mode is meant for code snippets from | |
6 | * indentation, it is nevertheless indented to the level given by the first | 6 | * function bodies. At this level, function definitions are not recognized | |
7 | * line of code. | 7 | * properly. | |
8 | * | |||
9 | * Even if later code has a smaller indentation, it is nevertheless indented to | |||
10 | * the level given by the first line of code. | |||
8 | * | 11 | * | |
9 | * In this particular test, the indentation is set to 5 and the tabulator | 12 | * In this particular test, the indentation is set to 5 and the tabulator | |
10 | * width is set to 8, to demonstrate an off-by-one error in | 13 | * width is set to 8, to demonstrate an off-by-one error in | |
11 | * main_prepare_parsing that has been fixed in indent.c 1.107 from 2021-10-05. | 14 | * main_prepare_parsing that has been fixed in indent.c 1.107 from 2021-10-05. | |
12 | * | 15 | * | |
13 | * The declaration in the first line is indented by 3 tabs, amounting to 24 | 16 | * The declaration in the first line is indented by 3 tabs, amounting to 24 | |
14 | * spaces. The initial indentation of the code is intended to be rounded down, | 17 | * spaces. The initial indentation of the code is intended to be rounded down, | |
15 | * to 4 levels of indentation, amounting to 20 spaces. | 18 | * to 4 levels of indentation, amounting to 20 spaces. | |
16 | */ | 19 | */ | |
17 | //indent input | 20 | //indent input | |
18 | int indented_by_24; | 21 | int indented_by_24; | |
19 | 22 | |||
20 | void function_in_column_1(void){} | 23 | void function_in_column_1(void){} | |
24 | ||||
25 | #if indented | |||
26 | #endif | |||
21 | //indent end | 27 | //indent end | |
22 | 28 | |||
23 | /* 5 spaces indentation, 8 spaces per tabulator */ | 29 | /* 5 spaces indentation, 8 spaces per tabulator */ | |
24 | //indent run -i5 -ts8 | 30 | //indent run -i5 -ts8 | |
25 | int indented_by_24; | 31 | int indented_by_24; | |
26 | 32 | |||
27 | void function_in_column_1(void) { | 33 | void function_in_column_1(void) { | |
28 | } | 34 | } | |
35 | ||||
36 | #if indented | |||
37 | #endif | |||
29 | //indent end | 38 | //indent end | |
30 | 39 | |||
31 | 40 | |||
32 | /* | 41 | /* | |
33 | * Labels are always indented 2 levels left of the code. The first line starts | 42 | * Labels are always indented 2 levels left of the code. The first line starts | |
34 | * at indentation level 3, the code in the function is therefore at level 4, | 43 | * at indentation level 3, the code in the function is therefore at level 4, | |
35 | * and the label is at level 2, sticking out of the code. | 44 | * and the label is at level 2, sticking out of the code. | |
36 | */ | 45 | */ | |
37 | //indent input | 46 | //indent input | |
38 | int indent_by_24; | 47 | int indent_by_24; | |
39 | 48 | |||
40 | void function(void) { | 49 | void function(void) { | |
41 | label:; | 50 | label:; |
--- src/tests/usr.bin/indent/fmt_decl.c 2023/06/10 17:56:29 1.54
+++ src/tests/usr.bin/indent/fmt_decl.c 2023/06/14 20:46:08 1.55
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: fmt_decl.c,v 1.54 2023/06/10 17:56:29 rillig Exp $ */ | 1 | /* $NetBSD: fmt_decl.c,v 1.55 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Tests for declarations of global variables, external functions, and local | 4 | * Tests for declarations of global variables, external functions, and local | |
5 | * variables. | 5 | * variables. | |
6 | * | 6 | * | |
7 | * See also: | 7 | * See also: | |
8 | * opt_di.c | 8 | * opt_di.c | |
9 | */ | 9 | */ | |
10 | 10 | |||
11 | /* See FreeBSD r303570 */ | 11 | /* See FreeBSD r303570 */ | |
12 | 12 | |||
13 | /* | 13 | /* | |
14 | * A type definition usually declares a single type, so there is no need to | 14 | * A type definition usually declares a single type, so there is no need to | |
@@ -1075,13 +1075,114 @@ b[] = {1, 2}; | @@ -1075,13 +1075,114 @@ b[] = {1, 2}; | |||
1075 | * When a type occurs at the top level, it forces a line break before. | 1075 | * When a type occurs at the top level, it forces a line break before. | |
1076 | */ | 1076 | */ | |
1077 | //indent input | 1077 | //indent input | |
1078 | __attribute__((__dead__)) void die(void) {} | 1078 | __attribute__((__dead__)) void die(void) {} | |
1079 | //indent end | 1079 | //indent end | |
1080 | 1080 | |||
1081 | //indent run | 1081 | //indent run | |
1082 | __attribute__((__dead__)) | 1082 | __attribute__((__dead__)) | |
1083 | void | 1083 | void | |
1084 | die(void) | 1084 | die(void) | |
1085 | { | 1085 | { | |
1086 | } | 1086 | } | |
1087 | //indent end | 1087 | //indent end | |
1088 | ||||
1089 | ||||
1090 | /* | |||
1091 | * In very rare cases, the type of a declarator might include literal tab | |||
1092 | * characters. This tab might affect the indentation of the declarator, but | |||
1093 | * only if it occurs before the declarator, and that is hard to achieve. | |||
1094 | */ | |||
1095 | //indent input | |||
1096 | int arr[sizeof " "]; | |||
1097 | //indent end | |||
1098 | ||||
1099 | //indent run-equals-input | |||
1100 | ||||
1101 | ||||
1102 | /* | |||
1103 | * The '}' of an initializer is not supposed to end the statement, it only ends | |||
1104 | * the brace level of the initializer expression. | |||
1105 | */ | |||
1106 | //indent input | |||
1107 | int multi_line[1][1][1] = { | |||
1108 | { | |||
1109 | { | |||
1110 | 1 | |||
1111 | }, | |||
1112 | }, | |||
1113 | }; | |||
1114 | int single_line[2][1][1] = {{{1},},{{2}}}; | |||
1115 | //indent end | |||
1116 | ||||
1117 | //indent run -di0 | |||
1118 | int multi_line[1][1][1] = { | |||
1119 | { | |||
1120 | { | |||
1121 | 1 | |||
1122 | }, | |||
1123 | }, | |||
1124 | }; | |||
1125 | int single_line[2][1][1] = {{{1},}, {{2}}}; | |||
1126 | //indent end | |||
1127 | ||||
1128 | ||||
1129 | /* | |||
1130 | * The '}' of an initializer is not supposed to end the statement, it only ends | |||
1131 | * the brace level of the initializer expression. | |||
1132 | */ | |||
1133 | //indent input | |||
1134 | { | |||
1135 | int multi_line = { | |||
1136 | { | |||
1137 | { | |||
1138 | b | |||
1139 | }, | |||
1140 | }, | |||
1141 | }; | |||
1142 | int single_line = {{{b},},{}}; | |||
1143 | } | |||
1144 | //indent end | |||
1145 | ||||
1146 | //indent run -di0 | |||
1147 | { | |||
1148 | int multi_line = { | |||
1149 | { | |||
1150 | { | |||
1151 | b | |||
1152 | }, | |||
1153 | }, | |||
1154 | }; | |||
1155 | int single_line = {{{b},}, {}}; | |||
1156 | } | |||
1157 | //indent end | |||
1158 | ||||
1159 | ||||
1160 | /* | |||
1161 | * In initializers, multi-line expressions don't have their second line | |||
1162 | * indented, even though they should. | |||
1163 | */ | |||
1164 | //indent input | |||
1165 | { | |||
1166 | multi_line = (int[]){ | |||
1167 | {1 | |||
1168 | +1}, | |||
1169 | {1 | |||
1170 | +1}, | |||
1171 | {1 | |||
1172 | +1}, | |||
1173 | }; | |||
1174 | } | |||
1175 | //indent end | |||
1176 | ||||
1177 | //indent run | |||
1178 | { | |||
1179 | multi_line = (int[]){ | |||
1180 | {1 | |||
1181 | + 1}, | |||
1182 | {1 | |||
1183 | + 1}, | |||
1184 | {1 | |||
1185 | + 1}, | |||
1186 | }; | |||
1187 | } | |||
1188 | //indent end |
--- src/tests/usr.bin/indent/lsym_preprocessing.c 2023/06/14 17:07:32 1.13
+++ src/tests/usr.bin/indent/lsym_preprocessing.c 2023/06/14 20:46:08 1.14
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: lsym_preprocessing.c,v 1.13 2023/06/14 17:07:32 rillig Exp $ */ | 1 | /* $NetBSD: lsym_preprocessing.c,v 1.14 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Tests for the token lsym_preprocessing, which represents a '#' that starts | 4 | * Tests for the token lsym_preprocessing, which represents a '#' that starts | |
5 | * a preprocessing line. | 5 | * a preprocessing line. | |
6 | * | 6 | * | |
7 | * #define | 7 | * #define | |
8 | * #ifdef | 8 | * #ifdef | |
9 | * #include | 9 | * #include | |
10 | * #line | 10 | * #line | |
11 | * #pragma | 11 | * #pragma | |
12 | * | 12 | * | |
13 | * The whole preprocessing line is processed separately from the main source | 13 | * The whole preprocessing line is processed separately from the main source | |
14 | * code, without much tokenizing or parsing. | 14 | * code, without much tokenizing or parsing. | |
@@ -297,13 +297,48 @@ int before; | @@ -297,13 +297,48 @@ int before; | |||
297 | #else | 297 | #else | |
298 | #elif 0 | 298 | #elif 0 | |
299 | #elifdef var | 299 | #elifdef var | |
300 | #endif | 300 | #endif | |
301 | 301 | |||
302 | #unknown | 302 | #unknown | |
303 | # 3 "file.c" | 303 | # 3 "file.c" | |
304 | exit 1 | 304 | exit 1 | |
305 | error: Standard Input:1: Unmatched #else | 305 | error: Standard Input:1: Unmatched #else | |
306 | error: Standard Input:2: Unmatched #elif | 306 | error: Standard Input:2: Unmatched #elif | |
307 | error: Standard Input:3: Unmatched #elifdef | 307 | error: Standard Input:3: Unmatched #elifdef | |
308 | error: Standard Input:4: Unmatched #endif | 308 | error: Standard Input:4: Unmatched #endif | |
309 | //indent end | 309 | //indent end | |
310 | ||||
311 | ||||
312 | /* | |||
313 | * The '#' can only occur at the beginning of a line, therefore indent does not | |||
314 | * care when it occurs in the middle of a line. | |||
315 | */ | |||
316 | //indent input | |||
317 | int no = #; | |||
318 | //indent end | |||
319 | ||||
320 | //indent run -di0 | |||
321 | int no = | |||
322 | #; | |||
323 | //indent end | |||
324 | ||||
325 | ||||
326 | /* | |||
327 | * Preprocessing directives may be indented; indent moves them to the beginning | |||
328 | * of a line. | |||
329 | */ | |||
330 | //indent input | |||
331 | #if 0 | |||
332 | #if 1 \ | |||
333 | || 2 | |||
334 | #endif | |||
335 | #endif | |||
336 | //indent end | |||
337 | ||||
338 | //indent run | |||
339 | #if 0 | |||
340 | #if 1 \ | |||
341 | || 2 | |||
342 | #endif | |||
343 | #endif | |||
344 | //indent end |
--- src/tests/usr.bin/indent/opt_bc.c 2023/06/14 14:11:28 1.11
+++ src/tests/usr.bin/indent/opt_bc.c 2023/06/14 20:46:08 1.12
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: opt_bc.c,v 1.11 2023/06/14 14:11:28 rillig Exp $ */ | 1 | /* $NetBSD: opt_bc.c,v 1.12 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Tests for the options '-bc' and '-nbc'. | 4 | * Tests for the options '-bc' and '-nbc'. | |
5 | * | 5 | * | |
6 | * The option '-bc' forces a newline after each comma in a declaration. | 6 | * The option '-bc' forces a newline after each comma in a declaration. | |
7 | * | 7 | * | |
8 | * The option '-nbc' removes line breaks between declarators. In most other | 8 | * The option '-nbc' removes line breaks between declarators. In most other | |
9 | * places, indent preserves line breaks. | 9 | * places, indent preserves line breaks. | |
10 | */ | 10 | */ | |
11 | 11 | |||
12 | //indent input | 12 | //indent input | |
13 | int a,b,c; | 13 | int a,b,c; | |
14 | void function_declaration(int a,int b,int c); | 14 | void function_declaration(int a,int b,int c); | |
@@ -111,26 +111,37 @@ int d; | @@ -111,26 +111,37 @@ int d; | |||
111 | //indent input | 111 | //indent input | |
112 | int a = 1, b = 2; | 112 | int a = 1, b = 2; | |
113 | int a = (1), b = 2; | 113 | int a = (1), b = 2; | |
114 | //indent end | 114 | //indent end | |
115 | 115 | |||
116 | //indent run -bc | 116 | //indent run -bc | |
117 | int a = 1, | 117 | int a = 1, | |
118 | b = 2; | 118 | b = 2; | |
119 | int a = (1), | 119 | int a = (1), | |
120 | b = 2; | 120 | b = 2; | |
121 | //indent end | 121 | //indent end | |
122 | 122 | |||
123 | 123 | |||
124 | //indent input | |||
125 | int a, | |||
126 | b, | |||
127 | c; | |||
128 | //indent end | |||
129 | ||||
130 | //indent run -nbc -di0 | |||
131 | int a, b, c; | |||
132 | //indent end | |||
133 | ||||
134 | ||||
124 | /* | 135 | /* | |
125 | * When declarations are too long to fit in a single line, they should not be | 136 | * When declarations are too long to fit in a single line, they should not be | |
126 | * joined. | 137 | * joined. | |
127 | */ | 138 | */ | |
128 | //indent input | 139 | //indent input | |
129 | { | 140 | { | |
130 | const struct paren_level *prev = state.prev_ps.paren.item, | 141 | const struct paren_level *prev = state.prev_ps.paren.item, | |
131 | *curr = ps.paren.item; | 142 | *curr = ps.paren.item; | |
132 | } | 143 | } | |
133 | //indent end | 144 | //indent end | |
134 | 145 | |||
135 | //indent run | 146 | //indent run | |
136 | // $ FIXME: The line becomes too long. | 147 | // $ FIXME: The line becomes too long. |
--- src/tests/usr.bin/indent/psym_rbrace.c 2022/04/24 09:04:12 1.3
+++ src/tests/usr.bin/indent/psym_rbrace.c 2023/06/14 20:46:08 1.4
@@ -1,15 +1,88 @@ | @@ -1,15 +1,88 @@ | |||
1 | /* $NetBSD: psym_rbrace.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */ | 1 | /* $NetBSD: psym_rbrace.c,v 1.4 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Tests for the parser symbol psym_rbrace, which represents '}' and finishes | 4 | * Tests for the parser symbol psym_rbrace, which represents '}' and finishes | |
5 | * the previous '{'. | 5 | * the previous '{'. | |
6 | * | 6 | * | |
7 | * See also: | 7 | * See also: | |
8 | * psym_lbrace.c | 8 | * psym_lbrace.c | |
9 | */ | 9 | */ | |
10 | 10 | |||
11 | ||||
12 | /* | |||
13 | * While it is a syntax error to have an unfinished declaration between braces, | |||
14 | * indent is forgiving enough to accept this input. | |||
15 | */ | |||
16 | //indent input | |||
17 | { | |||
18 | int | |||
19 | } | |||
20 | //indent end | |||
21 | ||||
22 | //indent run | |||
23 | { | |||
24 | int | |||
25 | } | |||
26 | exit 1 | |||
27 | error: Standard Input:3: Statement nesting error | |||
28 | error: Standard Input:3: Stuff missing from end of file | |||
29 | //indent end | |||
30 | ||||
31 | ||||
11 | //indent input | 32 | //indent input | |
12 | // TODO: add input | 33 | { | |
34 | do { | |||
35 | } while (cond) | |||
36 | } | |||
13 | //indent end | 37 | //indent end | |
14 | 38 | |||
39 | // XXX: Why doesn't indent complain about the missing semicolon? | |||
15 | //indent run-equals-input | 40 | //indent run-equals-input | |
41 | ||||
42 | ||||
43 | //indent input | |||
44 | { | |||
45 | if (cond) | |||
46 | } | |||
47 | //indent end | |||
48 | ||||
49 | //indent run | |||
50 | { | |||
51 | if (cond) | |||
52 | } | |||
53 | exit 1 | |||
54 | error: Standard Input:3: Statement nesting error | |||
55 | error: Standard Input:3: Stuff missing from end of file | |||
56 | //indent end | |||
57 | ||||
58 | ||||
59 | //indent input | |||
60 | { | |||
61 | switch (expr) | |||
62 | } | |||
63 | //indent end | |||
64 | ||||
65 | //indent run | |||
66 | { | |||
67 | switch (expr) | |||
68 | } | |||
69 | exit 1 | |||
70 | error: Standard Input:3: Statement nesting error | |||
71 | error: Standard Input:3: Stuff missing from end of file | |||
72 | //indent end | |||
73 | ||||
74 | ||||
75 | //indent input | |||
76 | { | |||
77 | while (cond) | |||
78 | } | |||
79 | //indent end | |||
80 | ||||
81 | //indent run | |||
82 | { | |||
83 | while (cond) | |||
84 | } | |||
85 | exit 1 | |||
86 | error: Standard Input:3: Statement nesting error | |||
87 | error: Standard Input:3: Stuff missing from end of file | |||
88 | //indent end |
--- src/usr.bin/indent/debug.c 2023/06/14 16:14:30 1.60
+++ src/usr.bin/indent/debug.c 2023/06/14 20:46:08 1.61
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: debug.c,v 1.60 2023/06/14 16:14:30 rillig Exp $ */ | 1 | /* $NetBSD: debug.c,v 1.61 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2023 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2023 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Roland Illig <rillig@NetBSD.org>. | 8 | * by Roland Illig <rillig@NetBSD.org>. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -20,27 +20,27 @@ | @@ -20,27 +20,27 @@ | |||
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include <sys/cdefs.h> | 32 | #include <sys/cdefs.h> | |
33 | __RCSID("$NetBSD: debug.c,v 1.60 2023/06/14 16:14:30 rillig Exp $"); | 33 | __RCSID("$NetBSD: debug.c,v 1.61 2023/06/14 20:46:08 rillig Exp $"); | |
34 | 34 | |||
35 | #include <stdarg.h> | 35 | #include <stdarg.h> | |
36 | #include <string.h> | 36 | #include <string.h> | |
37 | 37 | |||
38 | #include "indent.h" | 38 | #include "indent.h" | |
39 | 39 | |||
40 | #ifdef debug | 40 | #ifdef debug | |
41 | 41 | |||
42 | static struct { | 42 | static struct { | |
43 | // false show only the changes to the parser state | 43 | // false show only the changes to the parser state | |
44 | // true show unchanged parts of the parser state as well | 44 | // true show unchanged parts of the parser state as well | |
45 | bool full_parser_state; | 45 | bool full_parser_state; | |
46 | } config = { | 46 | } config = { | |
@@ -357,27 +357,27 @@ debug_parser_state(void) | @@ -357,27 +357,27 @@ debug_parser_state(void) | |||
357 | state.heading = "spacing inside a statement or declaration"; | 357 | state.heading = "spacing inside a statement or declaration"; | |
358 | debug_ps_bool(next_unary); | 358 | debug_ps_bool(next_unary); | |
359 | debug_ps_bool(want_blank); | 359 | debug_ps_bool(want_blank); | |
360 | debug_ps_int(ind_paren_level); | 360 | debug_ps_int(ind_paren_level); | |
361 | debug_ps_paren(); | 361 | debug_ps_paren(); | |
362 | 362 | |||
363 | state.heading = "indentation of comments"; | 363 | state.heading = "indentation of comments"; | |
364 | debug_ps_int(comment_ind); | 364 | debug_ps_int(comment_ind); | |
365 | debug_ps_int(comment_shift); | 365 | debug_ps_int(comment_shift); | |
366 | debug_ps_bool(comment_in_first_line); | 366 | debug_ps_bool(comment_in_first_line); | |
367 | 367 | |||
368 | state.heading = "vertical spacing"; | 368 | state.heading = "vertical spacing"; | |
369 | debug_ps_bool(break_after_comma); | 369 | debug_ps_bool(break_after_comma); | |
370 | debug_ps_bool(force_nl); | 370 | debug_ps_bool(want_newline); | |
371 | debug_ps_enum(declaration, declaration_name); | 371 | debug_ps_enum(declaration, declaration_name); | |
372 | debug_ps_bool(blank_line_after_decl); | 372 | debug_ps_bool(blank_line_after_decl); | |
373 | 373 | |||
374 | state.heading = NULL; | 374 | state.heading = NULL; | |
375 | debug_blank_line(); | 375 | debug_blank_line(); | |
376 | 376 | |||
377 | state.prev_ps = ps; | 377 | state.prev_ps = ps; | |
378 | state.ps_first = false; | 378 | state.ps_first = false; | |
379 | } | 379 | } | |
380 | 380 | |||
381 | void | 381 | void | |
382 | debug_psyms_stack(const char *situation) | 382 | debug_psyms_stack(const char *situation) | |
383 | { | 383 | { |
--- src/usr.bin/indent/indent.c 2023/06/14 19:05:40 1.366
+++ src/usr.bin/indent/indent.c 2023/06/14 20:46:08 1.367
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: indent.c,v 1.366 2023/06/14 19:05:40 rillig Exp $ */ | 1 | /* $NetBSD: indent.c,v 1.367 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. | 7 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. | |
8 | * Copyright (c) 1980, 1993 | 8 | * Copyright (c) 1980, 1993 | |
9 | * The Regents of the University of California. All rights reserved. | 9 | * The Regents of the University of California. All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -28,27 +28,27 @@ | @@ -28,27 +28,27 @@ | |||
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #include <sys/cdefs.h> | 40 | #include <sys/cdefs.h> | |
41 | __RCSID("$NetBSD: indent.c,v 1.366 2023/06/14 19:05:40 rillig Exp $"); | 41 | __RCSID("$NetBSD: indent.c,v 1.367 2023/06/14 20:46:08 rillig Exp $"); | |
42 | 42 | |||
43 | #include <sys/param.h> | 43 | #include <sys/param.h> | |
44 | #include <err.h> | 44 | #include <err.h> | |
45 | #include <stdarg.h> | 45 | #include <stdarg.h> | |
46 | #include <stdio.h> | 46 | #include <stdio.h> | |
47 | #include <stdlib.h> | 47 | #include <stdlib.h> | |
48 | #include <string.h> | 48 | #include <string.h> | |
49 | 49 | |||
50 | #include "indent.h" | 50 | #include "indent.h" | |
51 | 51 | |||
52 | struct options opt = { | 52 | struct options opt = { | |
53 | .brace_same_line = true, | 53 | .brace_same_line = true, | |
54 | .comment_delimiter_on_blank_line = true, | 54 | .comment_delimiter_on_blank_line = true, | |
@@ -177,27 +177,27 @@ ind_add(int ind, const char *s, size_t l | @@ -177,27 +177,27 @@ ind_add(int ind, const char *s, size_t l | |||
177 | else if (*p == '\t') | 177 | else if (*p == '\t') | |
178 | ind = next_tab(ind); | 178 | ind = next_tab(ind); | |
179 | else if (*p == '\b') | 179 | else if (*p == '\b') | |
180 | --ind; | 180 | --ind; | |
181 | else | 181 | else | |
182 | ++ind; | 182 | ++ind; | |
183 | } | 183 | } | |
184 | return ind; | 184 | return ind; | |
185 | } | 185 | } | |
186 | 186 | |||
187 | static void | 187 | static void | |
188 | init_globals(void) | 188 | init_globals(void) | |
189 | { | 189 | { | |
190 | ps_push(psym_stmt, false); | 190 | ps_push(psym_stmt, false); /* as a stop symbol */ | |
191 | ps.prev_lsym = lsym_semicolon; | 191 | ps.prev_lsym = lsym_semicolon; | |
192 | ps.lbrace_kind = psym_lbrace_block; | 192 | ps.lbrace_kind = psym_lbrace_block; | |
193 | 193 | |||
194 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | 194 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | |
195 | if (suffix != NULL) | 195 | if (suffix != NULL) | |
196 | backup_suffix = suffix; | 196 | backup_suffix = suffix; | |
197 | } | 197 | } | |
198 | 198 | |||
199 | static void | 199 | static void | |
200 | load_profiles(int argc, char **argv) | 200 | load_profiles(int argc, char **argv) | |
201 | { | 201 | { | |
202 | const char *profile_name = NULL; | 202 | const char *profile_name = NULL; | |
203 | 203 | |||
@@ -335,51 +335,51 @@ move_com_to_code(lexer_symbol lsym) | @@ -335,51 +335,51 @@ move_com_to_code(lexer_symbol lsym) | |||
335 | buf_add_char(&code, ' '); | 335 | buf_add_char(&code, ' '); | |
336 | buf_add_buf(&code, &com); | 336 | buf_add_buf(&code, &com); | |
337 | buf_clear(&com); | 337 | buf_clear(&com); | |
338 | ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; | 338 | ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; | |
339 | } | 339 | } | |
340 | 340 | |||
341 | static void | 341 | static void | |
342 | update_ps_lbrace_kind(lexer_symbol lsym) | 342 | update_ps_lbrace_kind(lexer_symbol lsym) | |
343 | { | 343 | { | |
344 | if (lsym == lsym_tag) { | 344 | if (lsym == lsym_tag) { | |
345 | ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : | 345 | ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : | |
346 | token.s[0] == 'u' ? psym_lbrace_union : | 346 | token.s[0] == 'u' ? psym_lbrace_union : | |
347 | psym_lbrace_enum; | 347 | psym_lbrace_enum; | |
348 | } else if (lsym != lsym_type_outside_parentheses | 348 | } else if (lsym == lsym_type_outside_parentheses | |
349 | && lsym != lsym_word | 349 | || lsym == lsym_word | |
350 | && lsym != lsym_lbrace) | 350 | || lsym == lsym_lbrace) { | |
351 | /* Keep the current '{' kind. */ | |||
352 | } else | |||
351 | ps.lbrace_kind = psym_lbrace_block; | 353 | ps.lbrace_kind = psym_lbrace_block; | |
352 | } | 354 | } | |
353 | 355 | |||
354 | static void | 356 | static void | |
355 | indent_declarator(int decl_ind, bool tabs_to_var) | 357 | indent_declarator(int decl_ind, bool tabs_to_var) | |
356 | { | 358 | { | |
357 | int base = ps.ind_level * opt.indent_size; | 359 | int base = ps.ind_level * opt.indent_size; | |
358 | int ind = base + (int)code.len; | 360 | int ind = ind_add(base, code.s, code.len); | |
359 | int target = base + decl_ind; | 361 | int target = base + decl_ind; | |
360 | size_t orig_code_len = code.len; | 362 | size_t orig_code_len = code.len; | |
361 | 363 | |||
362 | if (tabs_to_var) | 364 | if (tabs_to_var) | |
363 | for (int next; (next = next_tab(ind)) <= target; ind = next) | 365 | for (int next; (next = next_tab(ind)) <= target; ind = next) | |
364 | buf_add_char(&code, '\t'); | 366 | buf_add_char(&code, '\t'); | |
365 | ||||
366 | for (; ind < target; ind++) | 367 | for (; ind < target; ind++) | |
367 | buf_add_char(&code, ' '); | 368 | buf_add_char(&code, ' '); | |
368 | 369 | if (code.len == orig_code_len && ps.want_blank) | ||
369 | if (code.len == orig_code_len && ps.want_blank) { | |||
370 | buf_add_char(&code, ' '); | 370 | buf_add_char(&code, ' '); | |
371 | ps.want_blank = false; | 371 | ||
372 | } | 372 | ps.want_blank = false; | |
373 | ps.decl_indent_done = true; | 373 | ps.decl_indent_done = true; | |
374 | } | 374 | } | |
375 | 375 | |||
376 | static bool | 376 | static bool | |
377 | is_function_pointer_declaration(void) | 377 | is_function_pointer_declaration(void) | |
378 | { | 378 | { | |
379 | return ps.in_decl | 379 | return ps.in_decl | |
380 | && !ps.in_init | 380 | && !ps.in_init | |
381 | && !ps.decl_indent_done | 381 | && !ps.decl_indent_done | |
382 | && !ps.line_has_func_def | 382 | && !ps.line_has_func_def | |
383 | && ps.ind_paren_level == 0; | 383 | && ps.ind_paren_level == 0; | |
384 | } | 384 | } | |
385 | 385 | |||
@@ -546,27 +546,27 @@ process_preprocessing(void) | @@ -546,27 +546,27 @@ process_preprocessing(void) | |||
546 | 546 | |||
547 | static void | 547 | static void | |
548 | process_newline(void) | 548 | process_newline(void) | |
549 | { | 549 | { | |
550 | if (ps.prev_lsym == lsym_comma | 550 | if (ps.prev_lsym == lsym_comma | |
551 | && ps.paren.len == 0 && !ps.in_init | 551 | && ps.paren.len == 0 && !ps.in_init | |
552 | && !opt.break_after_comma && ps.break_after_comma | 552 | && !opt.break_after_comma && ps.break_after_comma | |
553 | && lab.len == 0 /* for preprocessing lines */ | 553 | && lab.len == 0 /* for preprocessing lines */ | |
554 | && com.len == 0) | 554 | && com.len == 0) | |
555 | goto stay_in_line; | 555 | goto stay_in_line; | |
556 | if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr | 556 | if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr | |
557 | && opt.brace_same_line | 557 | && opt.brace_same_line | |
558 | && com.len == 0) { | 558 | && com.len == 0) { | |
559 | ps.force_nl = true; | 559 | ps.want_newline = true; | |
560 | goto stay_in_line; | 560 | goto stay_in_line; | |
561 | } | 561 | } | |
562 | 562 | |||
563 | output_line(); | 563 | output_line(); | |
564 | 564 | |||
565 | stay_in_line: | 565 | stay_in_line: | |
566 | ++line_no; | 566 | ++line_no; | |
567 | } | 567 | } | |
568 | 568 | |||
569 | static bool | 569 | static bool | |
570 | want_blank_before_lparen(void) | 570 | want_blank_before_lparen(void) | |
571 | { | 571 | { | |
572 | if (opt.proc_calls_space) | 572 | if (opt.proc_calls_space) | |
@@ -581,133 +581,128 @@ want_blank_before_lparen(void) | @@ -581,133 +581,128 @@ want_blank_before_lparen(void) | |||
581 | return false; | 581 | return false; | |
582 | return true; | 582 | return true; | |
583 | } | 583 | } | |
584 | 584 | |||
585 | static void | 585 | static void | |
586 | process_lparen(void) | 586 | process_lparen(void) | |
587 | { | 587 | { | |
588 | 588 | |||
589 | if (is_function_pointer_declaration()) | 589 | if (is_function_pointer_declaration()) | |
590 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | 590 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | |
591 | else if (ps.want_blank && want_blank_before_lparen()) | 591 | else if (ps.want_blank && want_blank_before_lparen()) | |
592 | buf_add_char(&code, ' '); | 592 | buf_add_char(&code, ' '); | |
593 | ps.want_blank = false; | 593 | ps.want_blank = false; | |
594 | buf_add_char(&code, token.s[0]); | 594 | buf_add_buf(&code, &token); | |
595 | 595 | |||
596 | if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) | 596 | if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) | |
597 | ps.extra_expr_indent = eei_maybe; | 597 | ps.extra_expr_indent = eei_maybe; | |
598 | 598 | |||
599 | if (ps.in_var_decl && ps.psyms.len <= 3 && !ps.in_init) { | 599 | if (ps.in_var_decl && ps.psyms.len <= 3 && !ps.in_init) { | |
600 | parse(psym_stmt); /* prepare for function definition */ | 600 | parse(psym_stmt); /* prepare for function definition */ | |
601 | ps.in_var_decl = false; | 601 | ps.in_var_decl = false; | |
602 | } | 602 | } | |
603 | 603 | |||
604 | enum paren_level_cast cast = cast_unknown; | 604 | enum paren_level_cast cast = cast_unknown; | |
605 | if (ps.prev_lsym == lsym_offsetof | 605 | if (ps.prev_lsym == lsym_offsetof | |
606 | || ps.prev_lsym == lsym_sizeof | 606 | || ps.prev_lsym == lsym_sizeof | |
607 | || ps.prev_lsym == lsym_for | 607 | || ps.prev_lsym == lsym_for | |
608 | || ps.prev_lsym == lsym_if | 608 | || ps.prev_lsym == lsym_if | |
609 | || ps.prev_lsym == lsym_switch | 609 | || ps.prev_lsym == lsym_switch | |
610 | || ps.prev_lsym == lsym_while | 610 | || ps.prev_lsym == lsym_while | |
611 | || ps.line_has_func_def) | 611 | || ps.line_has_func_def) | |
612 | cast = cast_no; | 612 | cast = cast_no; | |
613 | 613 | |||
614 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast); | 614 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast); | |
615 | } | 615 | } | |
616 | 616 | |||
617 | static void | 617 | static void | |
618 | process_rparen(void) | 618 | process_rparen(void) | |
619 | { | 619 | { | |
620 | if (ps.paren.len == 0) { | 620 | if (ps.paren.len == 0) | |
621 | diag(0, "Extra '%c'", *token.s); | 621 | diag(0, "Extra '%c'", *token.s); | |
622 | goto unbalanced; | |||
623 | } | |||
624 | 622 | |||
625 | enum paren_level_cast cast = ps.paren.item[--ps.paren.len].cast; | 623 | ps.prev_paren_was_cast = ps.paren.len > 0 | |
626 | if (ps.in_func_def_params || (ps.line_has_decl && !ps.in_init)) | 624 | && ps.paren.item[--ps.paren.len].cast == cast_maybe | |
627 | cast = cast_no; | 625 | && !ps.in_func_def_params | |
628 | 626 | && !(ps.line_has_decl && !ps.in_init); | ||
629 | ps.prev_paren_was_cast = cast == cast_maybe; | 627 | if (ps.prev_paren_was_cast) { | |
630 | if (cast == cast_maybe) { | |||
631 | ps.next_unary = true; | 628 | ps.next_unary = true; | |
632 | ps.want_blank = opt.space_after_cast; | 629 | ps.want_blank = opt.space_after_cast; | |
633 | } else | 630 | } else | |
634 | ps.want_blank = true; | 631 | ps.want_blank = true; | |
635 | 632 | |||
636 | if (code.len == 0) | 633 | if (code.len == 0) | |
637 | ps.ind_paren_level = (int)ps.paren.len; | 634 | ps.ind_paren_level = (int)ps.paren.len; | |
638 | 635 | |||
639 | unbalanced: | 636 | buf_add_buf(&code, &token); | |
640 | buf_add_char(&code, token.s[0]); | |||
641 | 637 | |||
642 | if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { | 638 | if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { | |
643 | if (ps.extra_expr_indent == eei_maybe) | |||
644 | ps.extra_expr_indent = eei_last; | |||
645 | ps.force_nl = true; | |||
646 | ps.next_unary = true; | |||
647 | ps.in_stmt_or_decl = false; | |||
648 | parse(ps.spaced_expr_psym); | 639 | parse(ps.spaced_expr_psym); | |
649 | ps.spaced_expr_psym = psym_0; | 640 | ps.spaced_expr_psym = psym_0; | |
641 | ||||
642 | ps.want_newline = true; | |||
643 | ps.next_unary = true; | |||
644 | ps.in_stmt_or_decl = false; | |||
650 | ps.want_blank = true; | 645 | ps.want_blank = true; | |
651 | out.line_kind = lk_stmt_head; | 646 | out.line_kind = lk_stmt_head; | |
647 | if (ps.extra_expr_indent == eei_maybe) | |||
648 | ps.extra_expr_indent = eei_last; | |||
652 | } | 649 | } | |
653 | } | 650 | } | |
654 | 651 | |||
655 | static void | 652 | static void | |
656 | process_lbracket(void) | 653 | process_lbracket(void) | |
657 | { | 654 | { | |
658 | if (code.len > 0 | 655 | if (code.len > 0 | |
659 | && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) | 656 | && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) | |
660 | buf_add_char(&code, ' '); | 657 | buf_add_char(&code, ' '); | |
658 | buf_add_buf(&code, &token); | |||
661 | ps.want_blank = false; | 659 | ps.want_blank = false; | |
662 | buf_add_char(&code, token.s[0]); | |||
663 | 660 | |||
664 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast_no); | 661 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast_no); | |
665 | } | 662 | } | |
666 | 663 | |||
667 | static void | 664 | static void | |
668 | process_rbracket(void) | 665 | process_rbracket(void) | |
669 | { | 666 | { | |
670 | if (ps.paren.len == 0) { | 667 | if (ps.paren.len == 0) | |
671 | diag(0, "Extra '%c'", *token.s); | 668 | diag(0, "Extra '%c'", *token.s); | |
672 | goto unbalanced; | 669 | if (ps.paren.len > 0) | |
673 | } | 670 | ps.paren.len--; | |
674 | ps.paren.len--; | |||
675 | 671 | |||
676 | ps.want_blank = true; | |||
677 | if (code.len == 0) | 672 | if (code.len == 0) | |
678 | ps.ind_paren_level = (int)ps.paren.len; | 673 | ps.ind_paren_level = (int)ps.paren.len; | |
679 | 674 | |||
680 | unbalanced: | 675 | buf_add_buf(&code, &token); | |
681 | buf_add_char(&code, token.s[0]); | 676 | ps.want_blank = true; | |
682 | } | 677 | } | |
683 | 678 | |||
684 | static void | 679 | static void | |
685 | process_lbrace(void) | 680 | process_lbrace(void) | |
686 | { | 681 | { | |
687 | if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { | 682 | if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { | |
688 | ps.in_var_decl = true; // XXX: not really | 683 | ps.in_var_decl = true; // XXX: not really | |
689 | ps.in_init = true; | 684 | ps.in_init = true; | |
690 | } | 685 | } | |
691 | 686 | |||
692 | if (out.line_kind == lk_stmt_head) | 687 | if (out.line_kind == lk_stmt_head) | |
693 | out.line_kind = lk_other; | 688 | out.line_kind = lk_other; | |
694 | 689 | |||
695 | ps.in_stmt_or_decl = false; /* don't indent the {} */ | 690 | ps.in_stmt_or_decl = false; /* don't indent the {} */ | |
696 | 691 | |||
697 | if (ps.in_init) | 692 | if (ps.in_init) | |
698 | ps.init_level++; | 693 | ps.init_level++; | |
699 | else | 694 | else | |
700 | ps.force_nl = true; | 695 | ps.want_newline = true; | |
701 | 696 | |||
702 | if (code.len > 0 && !ps.in_init) { | 697 | if (code.len > 0 && !ps.in_init) { | |
703 | if (!opt.brace_same_line || | 698 | if (!opt.brace_same_line || | |
704 | (code.len > 0 && code.s[code.len - 1] == '}')) | 699 | (code.len > 0 && code.s[code.len - 1] == '}')) | |
705 | output_line(); | 700 | output_line(); | |
706 | else if (ps.in_func_def_params && !ps.in_var_decl) { | 701 | else if (ps.in_func_def_params && !ps.in_var_decl) { | |
707 | ps.ind_level_follow = 0; | 702 | ps.ind_level_follow = 0; | |
708 | if (opt.function_brace_split) | 703 | if (opt.function_brace_split) | |
709 | output_line(); | 704 | output_line(); | |
710 | else | 705 | else | |
711 | ps.want_blank = true; | 706 | ps.want_blank = true; | |
712 | } | 707 | } | |
713 | } | 708 | } | |
@@ -779,27 +774,27 @@ process_rbrace(void) | @@ -779,27 +774,27 @@ process_rbrace(void) | |||
779 | ? opt.decl_indent : opt.local_decl_indent; | 774 | ? opt.decl_indent : opt.local_decl_indent; | |
780 | } | 775 | } | |
781 | ps.in_decl = true; | 776 | ps.in_decl = true; | |
782 | } | 777 | } | |
783 | 778 | |||
784 | if (ps.psyms.len == 3) | 779 | if (ps.psyms.len == 3) | |
785 | out.line_kind = lk_func_end; | 780 | out.line_kind = lk_func_end; | |
786 | 781 | |||
787 | parse(psym_rbrace); | 782 | parse(psym_rbrace); | |
788 | 783 | |||
789 | if (!ps.in_var_decl | 784 | if (!ps.in_var_decl | |
790 | && ps.psyms.sym[ps.psyms.len - 1] != psym_do_stmt | 785 | && ps.psyms.sym[ps.psyms.len - 1] != psym_do_stmt | |
791 | && ps.psyms.sym[ps.psyms.len - 1] != psym_if_expr_stmt) | 786 | && ps.psyms.sym[ps.psyms.len - 1] != psym_if_expr_stmt) | |
792 | ps.force_nl = true; | 787 | ps.want_newline = true; | |
793 | } | 788 | } | |
794 | 789 | |||
795 | static void | 790 | static void | |
796 | process_period(void) | 791 | process_period(void) | |
797 | { | 792 | { | |
798 | if (code.len > 0 && code.s[code.len - 1] == ',') | 793 | if (code.len > 0 && code.s[code.len - 1] == ',') | |
799 | buf_add_char(&code, ' '); | 794 | buf_add_char(&code, ' '); | |
800 | buf_add_char(&code, '.'); | 795 | buf_add_char(&code, '.'); | |
801 | ps.want_blank = false; | 796 | ps.want_blank = false; | |
802 | } | 797 | } | |
803 | 798 | |||
804 | static void | 799 | static void | |
805 | process_unary_op(void) | 800 | process_unary_op(void) | |
@@ -836,41 +831,41 @@ process_comma(void) | @@ -836,41 +831,41 @@ process_comma(void) | |||
836 | /* indent leading commas and not the actual identifiers */ | 831 | /* indent leading commas and not the actual identifiers */ | |
837 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | 832 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | |
838 | } | 833 | } | |
839 | 834 | |||
840 | buf_add_char(&code, ','); | 835 | buf_add_char(&code, ','); | |
841 | 836 | |||
842 | if (ps.paren.len == 0) { | 837 | if (ps.paren.len == 0) { | |
843 | if (ps.init_level == 0) | 838 | if (ps.init_level == 0) | |
844 | ps.in_init = false; | 839 | ps.in_init = false; | |
845 | int typical_varname_length = 8; | 840 | int typical_varname_length = 8; | |
846 | if (ps.break_after_comma && (opt.break_after_comma || | 841 | if (ps.break_after_comma && (opt.break_after_comma || | |
847 | ind_add(compute_code_indent(), code.s, code.len) | 842 | ind_add(compute_code_indent(), code.s, code.len) | |
848 | >= opt.max_line_length - typical_varname_length)) | 843 | >= opt.max_line_length - typical_varname_length)) | |
849 | ps.force_nl = true; | 844 | ps.want_newline = true; | |
850 | } | 845 | } | |
851 | } | 846 | } | |
852 | 847 | |||
853 | static void | 848 | static void | |
854 | process_label_colon(void) | 849 | process_label_colon(void) | |
855 | { | 850 | { | |
856 | buf_add_buf(&lab, &code); | 851 | buf_add_buf(&lab, &code); | |
857 | buf_add_char(&lab, ':'); | 852 | buf_add_char(&lab, ':'); | |
858 | buf_clear(&code); | 853 | buf_clear(&code); | |
859 | 854 | |||
860 | if (ps.seen_case) | 855 | if (ps.seen_case) | |
861 | out.line_kind = lk_case_or_default; | 856 | out.line_kind = lk_case_or_default; | |
862 | ps.in_stmt_or_decl = false; | 857 | ps.in_stmt_or_decl = false; | |
863 | ps.force_nl = ps.seen_case; | 858 | ps.want_newline = ps.seen_case; | |
864 | ps.seen_case = false; | 859 | ps.seen_case = false; | |
865 | ps.want_blank = false; | 860 | ps.want_blank = false; | |
866 | } | 861 | } | |
867 | 862 | |||
868 | static void | 863 | static void | |
869 | process_other_colon(void) | 864 | process_other_colon(void) | |
870 | { | 865 | { | |
871 | buf_add_char(&code, ':'); | 866 | buf_add_char(&code, ':'); | |
872 | ps.want_blank = ps.decl_level == 0; | 867 | ps.want_blank = ps.decl_level == 0; | |
873 | } | 868 | } | |
874 | 869 | |||
875 | static void | 870 | static void | |
876 | process_semicolon(void) | 871 | process_semicolon(void) | |
@@ -905,27 +900,27 @@ process_semicolon(void) | @@ -905,27 +900,27 @@ process_semicolon(void) | |||
905 | ps.paren.len = 0; | 900 | ps.paren.len = 0; | |
906 | if (ps.spaced_expr_psym != psym_0) { | 901 | if (ps.spaced_expr_psym != psym_0) { | |
907 | parse(ps.spaced_expr_psym); | 902 | parse(ps.spaced_expr_psym); | |
908 | ps.spaced_expr_psym = psym_0; | 903 | ps.spaced_expr_psym = psym_0; | |
909 | } | 904 | } | |
910 | } | 905 | } | |
911 | buf_add_char(&code, ';'); | 906 | buf_add_char(&code, ';'); | |
912 | ps.want_blank = true; | 907 | ps.want_blank = true; | |
913 | ps.in_stmt_or_decl = ps.paren.len > 0; | 908 | ps.in_stmt_or_decl = ps.paren.len > 0; | |
914 | ps.decl_ind = 0; | 909 | ps.decl_ind = 0; | |
915 | 910 | |||
916 | if (ps.spaced_expr_psym == psym_0) { | 911 | if (ps.spaced_expr_psym == psym_0) { | |
917 | parse(psym_stmt); | 912 | parse(psym_stmt); | |
918 | ps.force_nl = true; | 913 | ps.want_newline = true; | |
919 | } | 914 | } | |
920 | } | 915 | } | |
921 | 916 | |||
922 | static void | 917 | static void | |
923 | process_type_outside_parentheses(void) | 918 | process_type_outside_parentheses(void) | |
924 | { | 919 | { | |
925 | parse(psym_decl); /* let the parser worry about indentation */ | 920 | parse(psym_decl); /* let the parser worry about indentation */ | |
926 | 921 | |||
927 | if (ps.prev_lsym == lsym_rparen && ps.psyms.len <= 2 && code.len > 0) | 922 | if (ps.prev_lsym == lsym_rparen && ps.psyms.len <= 2 && code.len > 0) | |
928 | output_line(); | 923 | output_line(); | |
929 | 924 | |||
930 | if (ps.in_func_def_params && opt.indent_parameters && | 925 | if (ps.in_func_def_params && opt.indent_parameters && | |
931 | ps.decl_level == 0) { | 926 | ps.decl_level == 0) { | |
@@ -958,57 +953,57 @@ process_word(lexer_symbol lsym) | @@ -958,57 +953,57 @@ process_word(lexer_symbol lsym) | |||
958 | buf_add_char(&code, ' '); | 953 | buf_add_char(&code, ' '); | |
959 | ps.want_blank = false; | 954 | ps.want_blank = false; | |
960 | 955 | |||
961 | } else if (!ps.in_init && !ps.decl_indent_done && | 956 | } else if (!ps.in_init && !ps.decl_indent_done && | |
962 | ps.ind_paren_level == 0) { | 957 | ps.ind_paren_level == 0) { | |
963 | if (opt.decl_indent == 0 | 958 | if (opt.decl_indent == 0 | |
964 | && code.len > 0 && code.s[code.len - 1] == '}') | 959 | && code.len > 0 && code.s[code.len - 1] == '}') | |
965 | ps.decl_ind = ind_add(0, code.s, code.len) + 1; | 960 | ps.decl_ind = ind_add(0, code.s, code.len) + 1; | |
966 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | 961 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | |
967 | ps.want_blank = false; | 962 | ps.want_blank = false; | |
968 | } | 963 | } | |
969 | 964 | |||
970 | } else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { | 965 | } else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { | |
971 | ps.force_nl = true; | 966 | ps.want_newline = true; | |
972 | ps.in_stmt_or_decl = false; | 967 | ps.in_stmt_or_decl = false; | |
973 | ps.next_unary = true; | 968 | ps.next_unary = true; | |
974 | parse(ps.spaced_expr_psym); | 969 | parse(ps.spaced_expr_psym); | |
975 | ps.spaced_expr_psym = psym_0; | 970 | ps.spaced_expr_psym = psym_0; | |
976 | } | 971 | } | |
977 | } | 972 | } | |
978 | 973 | |||
979 | static void | 974 | static void | |
980 | process_do(void) | 975 | process_do(void) | |
981 | { | 976 | { | |
982 | ps.in_stmt_or_decl = false; | 977 | ps.in_stmt_or_decl = false; | |
983 | ps.in_decl = false; | 978 | ps.in_decl = false; | |
984 | 979 | |||
985 | if (code.len > 0) | 980 | if (code.len > 0) | |
986 | output_line(); | 981 | output_line(); | |
987 | 982 | |||
988 | ps.force_nl = true; | 983 | ps.want_newline = true; | |
989 | parse(psym_do); | 984 | parse(psym_do); | |
990 | } | 985 | } | |
991 | 986 | |||
992 | static void | 987 | static void | |
993 | process_else(void) | 988 | process_else(void) | |
994 | { | 989 | { | |
995 | ps.in_stmt_or_decl = false; | 990 | ps.in_stmt_or_decl = false; | |
996 | 991 | |||
997 | if (code.len > 0 | 992 | if (code.len > 0 | |
998 | && !(opt.cuddle_else && code.s[code.len - 1] == '}')) | 993 | && !(opt.cuddle_else && code.s[code.len - 1] == '}')) | |
999 | output_line(); | 994 | output_line(); | |
1000 | 995 | |||
1001 | ps.force_nl = true; | 996 | ps.want_newline = true; | |
1002 | parse(psym_else); | 997 | parse(psym_else); | |
1003 | } | 998 | } | |
1004 | 999 | |||
1005 | static void | 1000 | static void | |
1006 | process_lsym(lexer_symbol lsym) | 1001 | process_lsym(lexer_symbol lsym) | |
1007 | { | 1002 | { | |
1008 | switch (lsym) { | 1003 | switch (lsym) { | |
1009 | /* INDENT OFF */ | 1004 | /* INDENT OFF */ | |
1010 | case lsym_preprocessing: process_preprocessing(); break; | 1005 | case lsym_preprocessing: process_preprocessing(); break; | |
1011 | case lsym_newline: process_newline(); break; | 1006 | case lsym_newline: process_newline(); break; | |
1012 | case lsym_comment: process_comment(); break; | 1007 | case lsym_comment: process_comment(); break; | |
1013 | case lsym_lparen: process_lparen(); break; | 1008 | case lsym_lparen: process_lparen(); break; | |
1014 | case lsym_lbracket: process_lbracket(); break; | 1009 | case lsym_lbracket: process_lbracket(); break; | |
@@ -1075,35 +1070,35 @@ indent(void) | @@ -1075,35 +1070,35 @@ indent(void) | |||
1075 | lexer_symbol lsym = lexi(); | 1070 | lexer_symbol lsym = lexi(); | |
1076 | 1071 | |||
1077 | debug_blank_line(); | 1072 | debug_blank_line(); | |
1078 | debug_printf("line %d: %s", line_no, lsym_name[lsym]); | 1073 | debug_printf("line %d: %s", line_no, lsym_name[lsym]); | |
1079 | debug_print_buf("token", &token); | 1074 | debug_print_buf("token", &token); | |
1080 | debug_buffers(); | 1075 | debug_buffers(); | |
1081 | debug_blank_line(); | 1076 | debug_blank_line(); | |
1082 | 1077 | |||
1083 | if (lsym == lsym_eof) | 1078 | if (lsym == lsym_eof) | |
1084 | return process_eof(); | 1079 | return process_eof(); | |
1085 | 1080 | |||
1086 | if (lsym == lsym_if && ps.prev_lsym == lsym_else | 1081 | if (lsym == lsym_if && ps.prev_lsym == lsym_else | |
1087 | && opt.else_if_in_same_line) | 1082 | && opt.else_if_in_same_line) | |
1088 | ps.force_nl = false; | 1083 | ps.want_newline = false; | |
1089 | 1084 | |||
1090 | if (lsym == lsym_preprocessing || lsym == lsym_newline) | 1085 | if (lsym == lsym_preprocessing || lsym == lsym_newline) | |
1091 | ps.force_nl = false; | 1086 | ps.want_newline = false; | |
1092 | else if (lsym == lsym_comment) { | 1087 | else if (lsym == lsym_comment) { | |
1093 | /* no special processing */ | 1088 | /* no special processing */ | |
1094 | } else { | 1089 | } else { | |
1095 | if (ps.force_nl && should_break_line(lsym)) { | 1090 | if (ps.want_newline && should_break_line(lsym)) { | |
1096 | ps.force_nl = false; | 1091 | ps.want_newline = false; | |
1097 | output_line(); | 1092 | output_line(); | |
1098 | } | 1093 | } | |
1099 | ps.in_stmt_or_decl = true; | 1094 | ps.in_stmt_or_decl = true; | |
1100 | if (com.len > 0) | 1095 | if (com.len > 0) | |
1101 | move_com_to_code(lsym); | 1096 | move_com_to_code(lsym); | |
1102 | update_ps_lbrace_kind(lsym); | 1097 | update_ps_lbrace_kind(lsym); | |
1103 | } | 1098 | } | |
1104 | 1099 | |||
1105 | process_lsym(lsym); | 1100 | process_lsym(lsym); | |
1106 | 1101 | |||
1107 | if (lsym != lsym_preprocessing | 1102 | if (lsym != lsym_preprocessing | |
1108 | && lsym != lsym_newline | 1103 | && lsym != lsym_newline | |
1109 | && lsym != lsym_comment) | 1104 | && lsym != lsym_comment) |
--- src/usr.bin/indent/indent.h 2023/06/14 19:05:40 1.196
+++ src/usr.bin/indent/indent.h 2023/06/14 20:46:08 1.197
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: indent.h,v 1.196 2023/06/14 19:05:40 rillig Exp $ */ | 1 | /* $NetBSD: indent.h,v 1.197 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | 4 | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |
5 | * | 5 | * | |
6 | * Copyright (c) 2001 Jens Schweikhardt | 6 | * Copyright (c) 2001 Jens Schweikhardt | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -262,30 +262,30 @@ struct paren_level { | @@ -262,30 +262,30 @@ struct paren_level { | |||
262 | int indent; /* indentation of the operand/argument, | 262 | int indent; /* indentation of the operand/argument, | |
263 | * relative to the enclosing statement; if | 263 | * relative to the enclosing statement; if | |
264 | * negative, reflected at -1 */ | 264 | * negative, reflected at -1 */ | |
265 | enum paren_level_cast { | 265 | enum paren_level_cast { | |
266 | cast_unknown, | 266 | cast_unknown, | |
267 | cast_maybe, | 267 | cast_maybe, | |
268 | cast_no, | 268 | cast_no, | |
269 | } cast; /* whether the parentheses form a type cast */ | 269 | } cast; /* whether the parentheses form a type cast */ | |
270 | }; | 270 | }; | |
271 | 271 | |||
272 | struct psym_stack { | 272 | struct psym_stack { | |
273 | parser_symbol *sym; | 273 | parser_symbol *sym; | |
274 | int *ind_level; | 274 | int *ind_level; | |
275 | size_t len; /* points to one behind the top of the stack; | 275 | size_t len; /* points to one behind the top of the stack; 1 | |
276 | * 1 at the top level of the file outside a | 276 | * at the top level of the file outside a | |
277 | * declaration or statement; 2 at the top | 277 | * declaration or statement; 2 at the top level | |
278 | * level */ | 278 | */ | |
279 | size_t cap; | 279 | size_t cap; | |
280 | }; | 280 | }; | |
281 | 281 | |||
282 | /* | 282 | /* | |
283 | * The parser state determines the layout of the formatted text. | 283 | * The parser state determines the layout of the formatted text. | |
284 | * | 284 | * | |
285 | * At each '#if', the parser state is copied so that the corresponding '#else' | 285 | * At each '#if', the parser state is copied so that the corresponding '#else' | |
286 | * lines start in the same state. | 286 | * lines start in the same state. | |
287 | * | 287 | * | |
288 | * In a function body, the number of block braces determines the indentation | 288 | * In a function body, the number of block braces determines the indentation | |
289 | * of statements and declarations. | 289 | * of statements and declarations. | |
290 | * | 290 | * | |
291 | * In a statement, the number of parentheses or brackets determines the | 291 | * In a statement, the number of parentheses or brackets determines the | |
@@ -383,29 +383,29 @@ extern struct parser_state { | @@ -383,29 +383,29 @@ extern struct parser_state { | |||
383 | 383 | |||
384 | /* Indentation of comments */ | 384 | /* Indentation of comments */ | |
385 | 385 | |||
386 | int comment_ind; /* indentation of the current comment */ | 386 | int comment_ind; /* indentation of the current comment */ | |
387 | int comment_shift; /* all but the first line of a boxed comment | 387 | int comment_shift; /* all but the first line of a boxed comment | |
388 | * are shifted this much to the right */ | 388 | * are shifted this much to the right */ | |
389 | bool comment_in_first_line; | 389 | bool comment_in_first_line; | |
390 | 390 | |||
391 | /* Vertical spacing */ | 391 | /* Vertical spacing */ | |
392 | 392 | |||
393 | bool break_after_comma; /* whether to add a newline after the next | 393 | bool break_after_comma; /* whether to add a newline after the next | |
394 | * comma; used in declarations but not in | 394 | * comma; used in declarations but not in | |
395 | * initializer lists */ | 395 | * initializer lists */ | |
396 | bool force_nl; /* whether the next token is forced to go to a | 396 | bool want_newline; /* whether the next token should go to a new | |
397 | * new line; used after 'if (expr)' and in | 397 | * line; used after 'if (expr)' and in similar | |
398 | * similar situations; tokens like '{' may | 398 | * situations; tokens like '{' or ';' may | |
399 | * ignore this */ | 399 | * ignore this */ | |
400 | 400 | |||
401 | enum declaration { | 401 | enum declaration { | |
402 | decl_no, /* no declaration anywhere nearby */ | 402 | decl_no, /* no declaration anywhere nearby */ | |
403 | decl_begin, /* collecting tokens of a declaration */ | 403 | decl_begin, /* collecting tokens of a declaration */ | |
404 | decl_end, /* finished a declaration */ | 404 | decl_end, /* finished a declaration */ | |
405 | } declaration; | 405 | } declaration; | |
406 | bool blank_line_after_decl; | 406 | bool blank_line_after_decl; | |
407 | } ps; | 407 | } ps; | |
408 | 408 | |||
409 | extern struct output_state { | 409 | extern struct output_state { | |
410 | enum line_kind { | 410 | enum line_kind { | |
411 | lk_other, | 411 | lk_other, |
--- src/usr.bin/indent/parse.c 2023/06/14 19:05:40 1.76
+++ src/usr.bin/indent/parse.c 2023/06/14 20:46:08 1.77
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: parse.c,v 1.76 2023/06/14 19:05:40 rillig Exp $ */ | 1 | /* $NetBSD: parse.c,v 1.77 2023/06/14 20:46:08 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1980, 1993 | 7 | * Copyright (c) 1980, 1993 | |
8 | * The Regents of the University of California. All rights reserved. | 8 | * The Regents of the University of California. All rights reserved. | |
9 | * All rights reserved. | 9 | * All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -28,40 +28,40 @@ | @@ -28,40 +28,40 @@ | |||
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #include <sys/cdefs.h> | 40 | #include <sys/cdefs.h> | |
41 | __RCSID("$NetBSD: parse.c,v 1.76 2023/06/14 19:05:40 rillig Exp $"); | 41 | __RCSID("$NetBSD: parse.c,v 1.77 2023/06/14 20:46:08 rillig Exp $"); | |
42 | 42 | |||
43 | #include <err.h> | |||
44 | #include <stdlib.h> | 43 | #include <stdlib.h> | |
45 | 44 | |||
46 | #include "indent.h" | 45 | #include "indent.h" | |
47 | 46 | |||
48 | /* | 47 | /* | |
49 | * Try to combine the statement on the top of the parse stack with the symbol | 48 | * Try to combine the statement on the top of the parse stack with the symbol | |
50 | * directly below it, replacing these two symbols with a single symbol. | 49 | * directly below it, replacing these two symbols with a single symbol. | |
51 | */ | 50 | */ | |
52 | static bool | 51 | static bool | |
53 | psyms_reduce_stmt(struct psym_stack *psyms) | 52 | psyms_reduce_stmt(void) | |
54 | { | 53 | { | |
54 | struct psym_stack *psyms = &ps.psyms; | |||
55 | switch (psyms->sym[psyms->len - 2]) { | 55 | switch (psyms->sym[psyms->len - 2]) { | |
56 | 56 | |||
57 | case psym_stmt: | 57 | case psym_stmt: | |
58 | psyms->sym[psyms->len-- - 2] = psym_stmt; | 58 | psyms->sym[psyms->len-- - 2] = psym_stmt; | |
59 | return true; | 59 | return true; | |
60 | 60 | |||
61 | case psym_do: | 61 | case psym_do: | |
62 | psyms->sym[psyms->len-- - 2] = psym_do_stmt; | 62 | psyms->sym[psyms->len-- - 2] = psym_do_stmt; | |
63 | ps.ind_level_follow = psyms->ind_level[psyms->len - 1]; | 63 | ps.ind_level_follow = psyms->ind_level[psyms->len - 1]; | |
64 | return true; | 64 | return true; | |
65 | 65 | |||
66 | case psym_if_expr: | 66 | case psym_if_expr: | |
67 | psyms->sym[psyms->len-- - 2] = psym_if_expr_stmt; | 67 | psyms->sym[psyms->len-- - 2] = psym_if_expr_stmt; | |
@@ -95,46 +95,47 @@ decl_level(void) | @@ -95,46 +95,47 @@ decl_level(void) | |||
95 | int level = 0; | 95 | int level = 0; | |
96 | for (size_t i = ps.psyms.len - 2; i > 0; i--) | 96 | for (size_t i = ps.psyms.len - 2; i > 0; i--) | |
97 | if (ps.psyms.sym[i] == psym_decl) | 97 | if (ps.psyms.sym[i] == psym_decl) | |
98 | level++; | 98 | level++; | |
99 | return level; | 99 | return level; | |
100 | } | 100 | } | |
101 | 101 | |||
102 | void | 102 | void | |
103 | ps_push(parser_symbol psym, bool follow) | 103 | ps_push(parser_symbol psym, bool follow) | |
104 | { | 104 | { | |
105 | if (ps.psyms.len == ps.psyms.cap) { | 105 | if (ps.psyms.len == ps.psyms.cap) { | |
106 | ps.psyms.cap += 16; | 106 | ps.psyms.cap += 16; | |
107 | ps.psyms.sym = nonnull(realloc(ps.psyms.sym, | 107 | ps.psyms.sym = nonnull(realloc(ps.psyms.sym, | |
108 | sizeof(ps.psyms.sym[0]) * ps.psyms.cap)); | 108 | sizeof(ps.psyms.sym[0]) * ps.psyms.cap)); | |
109 | ps.psyms.ind_level = nonnull(realloc(ps.psyms.ind_level, | 109 | ps.psyms.ind_level = nonnull(realloc(ps.psyms.ind_level, | |
110 | sizeof(ps.psyms.ind_level[0]) * ps.psyms.cap)); | 110 | sizeof(ps.psyms.ind_level[0]) * ps.psyms.cap)); | |
111 | } | 111 | } | |
112 | ps.psyms.len++; | 112 | ps.psyms.len++; | |
113 | ps.psyms.sym[ps.psyms.len - 1] = psym; | 113 | ps.psyms.sym[ps.psyms.len - 1] = psym; | |
114 | ps.psyms.ind_level[ps.psyms.len - 1] = | 114 | ps.psyms.ind_level[ps.psyms.len - 1] = | |
115 | follow ? ps.ind_level_follow : ps.ind_level; | 115 | follow ? ps.ind_level_follow : ps.ind_level; | |
116 | } | 116 | } | |
117 | 117 | |||
118 | /* | 118 | /* | |
119 | * Repeatedly try to reduce the top two symbols on the parse stack to a single | 119 | * Repeatedly try to reduce the top two symbols on the parse stack to a single | |
120 | * symbol, until no more reductions are possible. | 120 | * symbol, until no more reductions are possible. | |
121 | */ | 121 | */ | |
122 | static void | 122 | static void | |
123 | psyms_reduce(struct psym_stack *psyms) | 123 | psyms_reduce(void) | |
124 | { | 124 | { | |
125 | struct psym_stack *psyms = &ps.psyms; | |||
125 | again: | 126 | again: | |
126 | if (psyms->len >= 2 && psyms->sym[psyms->len - 1] == psym_stmt | 127 | if (psyms->len >= 2 && psyms->sym[psyms->len - 1] == psym_stmt | |
127 | && psyms_reduce_stmt(psyms)) | 128 | && psyms_reduce_stmt()) | |
128 | goto again; | 129 | goto again; | |
129 | if (psyms->sym[psyms->len - 1] == psym_while_expr && | 130 | if (psyms->sym[psyms->len - 1] == psym_while_expr && | |
130 | psyms->sym[psyms->len - 2] == psym_do_stmt) { | 131 | psyms->sym[psyms->len - 2] == psym_do_stmt) { | |
131 | psyms->len -= 2; | 132 | psyms->len -= 2; | |
132 | goto again; | 133 | goto again; | |
133 | } | 134 | } | |
134 | } | 135 | } | |
135 | 136 | |||
136 | static bool | 137 | static bool | |
137 | is_lbrace(parser_symbol psym) | 138 | is_lbrace(parser_symbol psym) | |
138 | { | 139 | { | |
139 | return psym == psym_lbrace_block | 140 | return psym == psym_lbrace_block | |
140 | || psym == psym_lbrace_struct | 141 | || psym == psym_lbrace_struct | |
@@ -146,27 +147,27 @@ is_lbrace(parser_symbol psym) | @@ -146,27 +147,27 @@ is_lbrace(parser_symbol psym) | |||
146 | * Shift the token onto the parser stack, then try to reduce it by combining it with | 147 | * Shift the token onto the parser stack, then try to reduce it by combining it with | |
147 | * previous tokens. | 148 | * previous tokens. | |
148 | */ | 149 | */ | |
149 | void | 150 | void | |
150 | parse(parser_symbol psym) | 151 | parse(parser_symbol psym) | |
151 | { | 152 | { | |
152 | debug_blank_line(); | 153 | debug_blank_line(); | |
153 | debug_println("parse token: %s", psym_name[psym]); | 154 | debug_println("parse token: %s", psym_name[psym]); | |
154 | 155 | |||
155 | struct psym_stack *psyms = &ps.psyms; | 156 | struct psym_stack *psyms = &ps.psyms; | |
156 | if (psym != psym_else) { | 157 | if (psym != psym_else) { | |
157 | while (psyms->sym[psyms->len - 1] == psym_if_expr_stmt) { | 158 | while (psyms->sym[psyms->len - 1] == psym_if_expr_stmt) { | |
158 | psyms->sym[psyms->len - 1] = psym_stmt; | 159 | psyms->sym[psyms->len - 1] = psym_stmt; | |
159 | psyms_reduce(&ps.psyms); | 160 | psyms_reduce(); | |
160 | } | 161 | } | |
161 | } | 162 | } | |
162 | 163 | |||
163 | switch (psym) { | 164 | switch (psym) { | |
164 | 165 | |||
165 | case psym_lbrace_block: | 166 | case psym_lbrace_block: | |
166 | case psym_lbrace_struct: | 167 | case psym_lbrace_struct: | |
167 | case psym_lbrace_union: | 168 | case psym_lbrace_union: | |
168 | case psym_lbrace_enum: | 169 | case psym_lbrace_enum: | |
169 | ps.break_after_comma = false; | 170 | ps.break_after_comma = false; | |
170 | if (psyms->sym[psyms->len - 1] == psym_decl | 171 | if (psyms->sym[psyms->len - 1] == psym_decl | |
171 | || psyms->sym[psyms->len - 1] == psym_stmt) | 172 | || psyms->sym[psyms->len - 1] == psym_stmt) | |
172 | ++ps.ind_level_follow; | 173 | ++ps.ind_level_follow; | |
@@ -176,27 +177,27 @@ parse(parser_symbol psym) | @@ -176,27 +177,27 @@ parse(parser_symbol psym) | |||
176 | 177 | |||
177 | /* for a switch, brace should be two levels out from | 178 | /* for a switch, brace should be two levels out from | |
178 | * the code */ | 179 | * the code */ | |
179 | if (psyms->sym[psyms->len - 1] == psym_switch_expr | 180 | if (psyms->sym[psyms->len - 1] == psym_switch_expr | |
180 | && opt.case_indent >= 1.0F) | 181 | && opt.case_indent >= 1.0F) | |
181 | --ps.ind_level; | 182 | --ps.ind_level; | |
182 | } | 183 | } | |
183 | 184 | |||
184 | ps_push(psym, false); | 185 | ps_push(psym, false); | |
185 | ps_push(psym_stmt, true); | 186 | ps_push(psym_stmt, true); | |
186 | break; | 187 | break; | |
187 | 188 | |||
188 | case psym_rbrace: | 189 | case psym_rbrace: | |
189 | /* stack should have <lbrace> <stmt> or <lbrace> <stmt_list> */ | 190 | /* stack should have <lbrace> <stmt> or <lbrace> <decl> */ | |
190 | if (!(psyms->len >= 2 | 191 | if (!(psyms->len >= 2 | |
191 | && is_lbrace(psyms->sym[psyms->len - 2]))) { | 192 | && is_lbrace(psyms->sym[psyms->len - 2]))) { | |
192 | diag(1, "Statement nesting error"); | 193 | diag(1, "Statement nesting error"); | |
193 | break; | 194 | break; | |
194 | } | 195 | } | |
195 | ps.ind_level = ps.ind_level_follow = | 196 | ps.ind_level = ps.ind_level_follow = | |
196 | psyms->ind_level[psyms->len-- - 2]; | 197 | psyms->ind_level[psyms->len-- - 2]; | |
197 | psyms->sym[psyms->len - 1] = psym_stmt; | 198 | psyms->sym[psyms->len - 1] = psym_stmt; | |
198 | break; | 199 | break; | |
199 | 200 | |||
200 | case psym_decl: | 201 | case psym_decl: | |
201 | if (psyms->sym[psyms->len - 1] == psym_decl) | 202 | if (psyms->sym[psyms->len - 1] == psym_decl) | |
202 | break; /* only put one declaration onto stack */ | 203 | break; /* only put one declaration onto stack */ | |
@@ -247,16 +248,16 @@ parse(parser_symbol psym) | @@ -247,16 +248,16 @@ parse(parser_symbol psym) | |||
247 | ps_push(psym_while_expr, false); | 248 | ps_push(psym_while_expr, false); | |
248 | } else { | 249 | } else { | |
249 | ps_push(psym_while_expr, true); | 250 | ps_push(psym_while_expr, true); | |
250 | ++ps.ind_level_follow; | 251 | ++ps.ind_level_follow; | |
251 | } | 252 | } | |
252 | break; | 253 | break; | |
253 | 254 | |||
254 | default: | 255 | default: | |
255 | diag(1, "Unknown code to parser"); | 256 | diag(1, "Unknown code to parser"); | |
256 | return; | 257 | return; | |
257 | } | 258 | } | |
258 | 259 | |||
259 | debug_psyms_stack("before reduction"); | 260 | debug_psyms_stack("before reduction"); | |
260 | psyms_reduce(&ps.psyms); | 261 | psyms_reduce(); | |
261 | debug_psyms_stack("after reduction"); | 262 | debug_psyms_stack("after reduction"); | |
262 | } | 263 | } |