indent: rename misleading variable The name started with 'line_start', but the value is not always the value from the beginning of the line. No functional change.diff -r1.52 -r1.53 src/usr.bin/indent/debug.c
(rillig)
--- src/usr.bin/indent/debug.c 2023/06/10 20:37:12 1.52
+++ src/usr.bin/indent/debug.c 2023/06/10 21:36:38 1.53
@@ -1,399 +1,399 @@ | @@ -1,399 +1,399 @@ | |||
1 | /* $NetBSD: debug.c,v 1.52 2023/06/10 20:37:12 rillig Exp $ */ | 1 | /* $NetBSD: debug.c,v 1.53 2023/06/10 21:36:38 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. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 16 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 17 | * documentation and/or other materials provided with the distribution. | |
18 | * | 18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
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.52 2023/06/10 20:37:12 rillig Exp $"); | 33 | __RCSID("$NetBSD: debug.c,v 1.53 2023/06/10 21:36:38 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 | /*- | 43 | /*- | |
44 | * false show only the changes to the parser state | 44 | * false show only the changes to the parser state | |
45 | * true show unchanged parts of the parser state as well | 45 | * true show unchanged parts of the parser state as well | |
46 | */ | 46 | */ | |
47 | bool full_parser_state; | 47 | bool full_parser_state; | |
48 | } config = { | 48 | } config = { | |
49 | .full_parser_state = false, | 49 | .full_parser_state = false, | |
50 | }; | 50 | }; | |
51 | 51 | |||
52 | const char *const lsym_name[] = { | 52 | const char *const lsym_name[] = { | |
53 | "eof", | 53 | "eof", | |
54 | "preprocessing", | 54 | "preprocessing", | |
55 | "newline", | 55 | "newline", | |
56 | "comment", | 56 | "comment", | |
57 | "lparen", | 57 | "lparen", | |
58 | "rparen", | 58 | "rparen", | |
59 | "lbracket", | 59 | "lbracket", | |
60 | "rbracket", | 60 | "rbracket", | |
61 | "lbrace", | 61 | "lbrace", | |
62 | "rbrace", | 62 | "rbrace", | |
63 | "period", | 63 | "period", | |
64 | "unary_op", | 64 | "unary_op", | |
65 | "sizeof", | 65 | "sizeof", | |
66 | "offsetof", | 66 | "offsetof", | |
67 | "postfix_op", | 67 | "postfix_op", | |
68 | "binary_op", | 68 | "binary_op", | |
69 | "question", | 69 | "question", | |
70 | "question_colon", | 70 | "question_colon", | |
71 | "comma", | 71 | "comma", | |
72 | "typedef", | 72 | "typedef", | |
73 | "modifier", | 73 | "modifier", | |
74 | "tag", | 74 | "tag", | |
75 | "type_outside_parentheses", | 75 | "type_outside_parentheses", | |
76 | "type_in_parentheses", | 76 | "type_in_parentheses", | |
77 | "word", | 77 | "word", | |
78 | "funcname", | 78 | "funcname", | |
79 | "label_colon", | 79 | "label_colon", | |
80 | "other_colon", | 80 | "other_colon", | |
81 | "semicolon", | 81 | "semicolon", | |
82 | "case", | 82 | "case", | |
83 | "default", | 83 | "default", | |
84 | "do", | 84 | "do", | |
85 | "else", | 85 | "else", | |
86 | "for", | 86 | "for", | |
87 | "if", | 87 | "if", | |
88 | "switch", | 88 | "switch", | |
89 | "while", | 89 | "while", | |
90 | "return", | 90 | "return", | |
91 | }; | 91 | }; | |
92 | 92 | |||
93 | const char *const psym_name[] = { | 93 | const char *const psym_name[] = { | |
94 | "-", | 94 | "-", | |
95 | "{block", | 95 | "{block", | |
96 | "{struct", | 96 | "{struct", | |
97 | "{union", | 97 | "{union", | |
98 | "{enum", | 98 | "{enum", | |
99 | "}", | 99 | "}", | |
100 | "decl", | 100 | "decl", | |
101 | "stmt", | 101 | "stmt", | |
102 | "stmt_list", | 102 | "stmt_list", | |
103 | "for_exprs", | 103 | "for_exprs", | |
104 | "if_expr", | 104 | "if_expr", | |
105 | "if_expr_stmt", | 105 | "if_expr_stmt", | |
106 | "if_expr_stmt_else", | 106 | "if_expr_stmt_else", | |
107 | "else", | 107 | "else", | |
108 | "switch_expr", | 108 | "switch_expr", | |
109 | "do", | 109 | "do", | |
110 | "do_stmt", | 110 | "do_stmt", | |
111 | "while_expr", | 111 | "while_expr", | |
112 | }; | 112 | }; | |
113 | 113 | |||
114 | static const char *const declaration_name[] = { | 114 | static const char *const declaration_name[] = { | |
115 | "no", | 115 | "no", | |
116 | "begin", | 116 | "begin", | |
117 | "end", | 117 | "end", | |
118 | }; | 118 | }; | |
119 | 119 | |||
120 | const char *const paren_level_cast_name[] = { | 120 | const char *const paren_level_cast_name[] = { | |
121 | "(unknown cast)", | 121 | "(unknown cast)", | |
122 | "(maybe cast)", | 122 | "(maybe cast)", | |
123 | "(no cast)", | 123 | "(no cast)", | |
124 | }; | 124 | }; | |
125 | 125 | |||
126 | const char *const line_kind_name[] = { | 126 | const char *const line_kind_name[] = { | |
127 | "other", | 127 | "other", | |
128 | "blank", | 128 | "blank", | |
129 | "#if", | 129 | "#if", | |
130 | "#endif", | 130 | "#endif", | |
131 | "stmt head", | 131 | "stmt head", | |
132 | "}", | 132 | "}", | |
133 | "block comment", | 133 | "block comment", | |
134 | "case/default", | 134 | "case/default", | |
135 | }; | 135 | }; | |
136 | 136 | |||
137 | static const char *const extra_expr_indent_name[] = { | 137 | static const char *const extra_expr_indent_name[] = { | |
138 | "no", | 138 | "no", | |
139 | "maybe", | 139 | "maybe", | |
140 | "last", | 140 | "last", | |
141 | }; | 141 | }; | |
142 | 142 | |||
143 | static struct { | 143 | static struct { | |
144 | struct parser_state prev_ps; | 144 | struct parser_state prev_ps; | |
145 | bool ps_first; | 145 | bool ps_first; | |
146 | const char *heading; | 146 | const char *heading; | |
147 | unsigned wrote_newlines; | 147 | unsigned wrote_newlines; | |
148 | } state = { | 148 | } state = { | |
149 | .ps_first = true, | 149 | .ps_first = true, | |
150 | .wrote_newlines = 1, | 150 | .wrote_newlines = 1, | |
151 | }; | 151 | }; | |
152 | 152 | |||
153 | void | 153 | void | |
154 | debug_printf(const char *fmt, ...) | 154 | debug_printf(const char *fmt, ...) | |
155 | { | 155 | { | |
156 | FILE *f = output == stdout ? stderr : stdout; | 156 | FILE *f = output == stdout ? stderr : stdout; | |
157 | va_list ap; | 157 | va_list ap; | |
158 | 158 | |||
159 | if (state.heading != NULL) { | 159 | if (state.heading != NULL) { | |
160 | fprintf(f, "%s\n", state.heading); | 160 | fprintf(f, "%s\n", state.heading); | |
161 | state.heading = NULL; | 161 | state.heading = NULL; | |
162 | } | 162 | } | |
163 | va_start(ap, fmt); | 163 | va_start(ap, fmt); | |
164 | vfprintf(f, fmt, ap); | 164 | vfprintf(f, fmt, ap); | |
165 | va_end(ap); | 165 | va_end(ap); | |
166 | state.wrote_newlines = 0; | 166 | state.wrote_newlines = 0; | |
167 | } | 167 | } | |
168 | 168 | |||
169 | void | 169 | void | |
170 | debug_println(const char *fmt, ...) | 170 | debug_println(const char *fmt, ...) | |
171 | { | 171 | { | |
172 | FILE *f = output == stdout ? stderr : stdout; | 172 | FILE *f = output == stdout ? stderr : stdout; | |
173 | va_list ap; | 173 | va_list ap; | |
174 | 174 | |||
175 | if (state.heading != NULL) { | 175 | if (state.heading != NULL) { | |
176 | fprintf(f, "%s\n", state.heading); | 176 | fprintf(f, "%s\n", state.heading); | |
177 | state.heading = NULL; | 177 | state.heading = NULL; | |
178 | state.wrote_newlines = 1; | 178 | state.wrote_newlines = 1; | |
179 | } | 179 | } | |
180 | va_start(ap, fmt); | 180 | va_start(ap, fmt); | |
181 | vfprintf(f, fmt, ap); | 181 | vfprintf(f, fmt, ap); | |
182 | va_end(ap); | 182 | va_end(ap); | |
183 | fprintf(f, "\n"); | 183 | fprintf(f, "\n"); | |
184 | state.wrote_newlines = fmt[0] == '\0' ? state.wrote_newlines + 1 : 1; | 184 | state.wrote_newlines = fmt[0] == '\0' ? state.wrote_newlines + 1 : 1; | |
185 | } | 185 | } | |
186 | 186 | |||
187 | void | 187 | void | |
188 | debug_blank_line(void) | 188 | debug_blank_line(void) | |
189 | { | 189 | { | |
190 | while (state.wrote_newlines < 2) | 190 | while (state.wrote_newlines < 2) | |
191 | debug_println(""); | 191 | debug_println(""); | |
192 | } | 192 | } | |
193 | 193 | |||
194 | void | 194 | void | |
195 | debug_vis_range(const char *prefix, const char *s, size_t len, | 195 | debug_vis_range(const char *prefix, const char *s, size_t len, | |
196 | const char *suffix) | 196 | const char *suffix) | |
197 | { | 197 | { | |
198 | debug_printf("%s", prefix); | 198 | debug_printf("%s", prefix); | |
199 | for (size_t i = 0; i < len; i++) { | 199 | for (size_t i = 0; i < len; i++) { | |
200 | const char *p = s + i; | 200 | const char *p = s + i; | |
201 | if (*p == '\\' || *p == '"') | 201 | if (*p == '\\' || *p == '"') | |
202 | debug_printf("\\%c", *p); | 202 | debug_printf("\\%c", *p); | |
203 | else if (isprint((unsigned char)*p)) | 203 | else if (isprint((unsigned char)*p)) | |
204 | debug_printf("%c", *p); | 204 | debug_printf("%c", *p); | |
205 | else if (*p == '\n') | 205 | else if (*p == '\n') | |
206 | debug_printf("\\n"); | 206 | debug_printf("\\n"); | |
207 | else if (*p == '\t') | 207 | else if (*p == '\t') | |
208 | debug_printf("\\t"); | 208 | debug_printf("\\t"); | |
209 | else | 209 | else | |
210 | debug_printf("\\x%02x", (unsigned char)*p); | 210 | debug_printf("\\x%02x", (unsigned char)*p); | |
211 | } | 211 | } | |
212 | debug_printf("%s", suffix); | 212 | debug_printf("%s", suffix); | |
213 | } | 213 | } | |
214 | 214 | |||
215 | void | 215 | void | |
216 | debug_print_buf(const char *name, const struct buffer *buf) | 216 | debug_print_buf(const char *name, const struct buffer *buf) | |
217 | { | 217 | { | |
218 | if (buf->len > 0) { | 218 | if (buf->len > 0) { | |
219 | debug_printf(" %s ", name); | 219 | debug_printf(" %s ", name); | |
220 | debug_vis_range("\"", buf->s, buf->len, "\""); | 220 | debug_vis_range("\"", buf->s, buf->len, "\""); | |
221 | } | 221 | } | |
222 | } | 222 | } | |
223 | 223 | |||
224 | void | 224 | void | |
225 | debug_buffers(void) | 225 | debug_buffers(void) | |
226 | { | 226 | { | |
227 | debug_print_buf("label", &lab); | 227 | debug_print_buf("label", &lab); | |
228 | debug_print_buf("code", &code); | 228 | debug_print_buf("code", &code); | |
229 | debug_print_buf("comment", &com); | 229 | debug_print_buf("comment", &com); | |
230 | debug_blank_line(); | 230 | debug_blank_line(); | |
231 | } | 231 | } | |
232 | 232 | |||
233 | static void | 233 | static void | |
234 | write_ps_bool(const char *name, bool prev, bool curr) | 234 | write_ps_bool(const char *name, bool prev, bool curr) | |
235 | { | 235 | { | |
236 | if (!state.ps_first && curr != prev) { | 236 | if (!state.ps_first && curr != prev) { | |
237 | char diff = " -+x"[(prev ? 1 : 0) + (curr ? 2 : 0)]; | 237 | char diff = " -+x"[(prev ? 1 : 0) + (curr ? 2 : 0)]; | |
238 | debug_println(" [%c] ps.%s", diff, name); | 238 | debug_println(" [%c] ps.%s", diff, name); | |
239 | } else if (config.full_parser_state || state.ps_first) | 239 | } else if (config.full_parser_state || state.ps_first) | |
240 | debug_println(" [%c] ps.%s", curr ? 'x' : ' ', name); | 240 | debug_println(" [%c] ps.%s", curr ? 'x' : ' ', name); | |
241 | } | 241 | } | |
242 | 242 | |||
243 | static void | 243 | static void | |
244 | write_ps_int(const char *name, int prev, int curr) | 244 | write_ps_int(const char *name, int prev, int curr) | |
245 | { | 245 | { | |
246 | if (!state.ps_first && curr != prev) | 246 | if (!state.ps_first && curr != prev) | |
247 | debug_println(" %3d -> %3d ps.%s", prev, curr, name); | 247 | debug_println(" %3d -> %3d ps.%s", prev, curr, name); | |
248 | else if (config.full_parser_state || state.ps_first) | 248 | else if (config.full_parser_state || state.ps_first) | |
249 | debug_println(" %3d ps.%s", curr, name); | 249 | debug_println(" %3d ps.%s", curr, name); | |
250 | } | 250 | } | |
251 | 251 | |||
252 | static void | 252 | static void | |
253 | write_ps_enum(const char *name, const char *prev, const char *curr) | 253 | write_ps_enum(const char *name, const char *prev, const char *curr) | |
254 | { | 254 | { | |
255 | if (!state.ps_first && strcmp(prev, curr) != 0) | 255 | if (!state.ps_first && strcmp(prev, curr) != 0) | |
256 | debug_println(" %3s -> %3s ps.%s", prev, curr, name); | 256 | debug_println(" %3s -> %3s ps.%s", prev, curr, name); | |
257 | else if (config.full_parser_state || state.ps_first) | 257 | else if (config.full_parser_state || state.ps_first) | |
258 | debug_println(" %10s ps.%s", curr, name); | 258 | debug_println(" %10s ps.%s", curr, name); | |
259 | } | 259 | } | |
260 | 260 | |||
261 | static bool | 261 | static bool | |
262 | ps_paren_has_changed(void) | 262 | ps_paren_has_changed(void) | |
263 | { | 263 | { | |
264 | if (state.prev_ps.nparen != ps.nparen) | 264 | if (state.prev_ps.nparen != ps.nparen) | |
265 | return true; | 265 | return true; | |
266 | 266 | |||
267 | const struct paren_level *prev = state.prev_ps.paren, *curr = ps.paren; | 267 | const struct paren_level *prev = state.prev_ps.paren, *curr = ps.paren; | |
268 | for (int i = 0; i < ps.nparen; i++) | 268 | for (int i = 0; i < ps.nparen; i++) | |
269 | if (curr[i].indent != prev[i].indent | 269 | if (curr[i].indent != prev[i].indent | |
270 | || curr[i].cast != prev[i].cast) | 270 | || curr[i].cast != prev[i].cast) | |
271 | return true; | 271 | return true; | |
272 | return false; | 272 | return false; | |
273 | } | 273 | } | |
274 | 274 | |||
275 | static void | 275 | static void | |
276 | debug_ps_paren(void) | 276 | debug_ps_paren(void) | |
277 | { | 277 | { | |
278 | if (!config.full_parser_state && !ps_paren_has_changed() | 278 | if (!config.full_parser_state && !ps_paren_has_changed() | |
279 | && !state.ps_first) | 279 | && !state.ps_first) | |
280 | return; | 280 | return; | |
281 | 281 | |||
282 | debug_printf(" ps.paren:"); | 282 | debug_printf(" ps.paren:"); | |
283 | for (int i = 0; i < ps.nparen; i++) { | 283 | for (int i = 0; i < ps.nparen; i++) { | |
284 | debug_printf(" %s%d", | 284 | debug_printf(" %s%d", | |
285 | paren_level_cast_name[ps.paren[i].cast], | 285 | paren_level_cast_name[ps.paren[i].cast], | |
286 | ps.paren[i].indent); | 286 | ps.paren[i].indent); | |
287 | } | 287 | } | |
288 | if (ps.nparen == 0) | 288 | if (ps.nparen == 0) | |
289 | debug_printf(" none"); | 289 | debug_printf(" none"); | |
290 | debug_println(""); | 290 | debug_println(""); | |
291 | } | 291 | } | |
292 | 292 | |||
293 | static bool | 293 | static bool | |
294 | ps_di_stack_has_changed(void) | 294 | ps_di_stack_has_changed(void) | |
295 | { | 295 | { | |
296 | if (state.prev_ps.decl_level != ps.decl_level) | 296 | if (state.prev_ps.decl_level != ps.decl_level) | |
297 | return true; | 297 | return true; | |
298 | for (int i = 0; i < ps.decl_level; i++) | 298 | for (int i = 0; i < ps.decl_level; i++) | |
299 | if (state.prev_ps.di_stack[i] != ps.di_stack[i]) | 299 | if (state.prev_ps.di_stack[i] != ps.di_stack[i]) | |
300 | return true; | 300 | return true; | |
301 | return false; | 301 | return false; | |
302 | } | 302 | } | |
303 | 303 | |||
304 | static void | 304 | static void | |
305 | debug_ps_di_stack(void) | 305 | debug_ps_di_stack(void) | |
306 | { | 306 | { | |
307 | bool changed = ps_di_stack_has_changed(); | 307 | bool changed = ps_di_stack_has_changed(); | |
308 | if (!config.full_parser_state && !changed && !state.ps_first) | 308 | if (!config.full_parser_state && !changed && !state.ps_first) | |
309 | return; | 309 | return; | |
310 | 310 | |||
311 | debug_printf(" %s ps.di_stack:", changed ? "->" : " "); | 311 | debug_printf(" %s ps.di_stack:", changed ? "->" : " "); | |
312 | for (int i = 0; i < ps.decl_level; i++) | 312 | for (int i = 0; i < ps.decl_level; i++) | |
313 | debug_printf(" %d", ps.di_stack[i]); | 313 | debug_printf(" %d", ps.di_stack[i]); | |
314 | if (ps.decl_level == 0) | 314 | if (ps.decl_level == 0) | |
315 | debug_printf(" none"); | 315 | debug_printf(" none"); | |
316 | debug_println(""); | 316 | debug_println(""); | |
317 | } | 317 | } | |
318 | 318 | |||
319 | #define debug_ps_bool(name) \ | 319 | #define debug_ps_bool(name) \ | |
320 | write_ps_bool(#name, state.prev_ps.name, ps.name) | 320 | write_ps_bool(#name, state.prev_ps.name, ps.name) | |
321 | #define debug_ps_int(name) \ | 321 | #define debug_ps_int(name) \ | |
322 | write_ps_int(#name, state.prev_ps.name, ps.name) | 322 | write_ps_int(#name, state.prev_ps.name, ps.name) | |
323 | #define debug_ps_enum(name, names) \ | 323 | #define debug_ps_enum(name, names) \ | |
324 | write_ps_enum(#name, (names)[state.prev_ps.name], (names)[ps.name]) | 324 | write_ps_enum(#name, (names)[state.prev_ps.name], (names)[ps.name]) | |
325 | 325 | |||
326 | void | 326 | void | |
327 | debug_parser_state(void) | 327 | debug_parser_state(void) | |
328 | { | 328 | { | |
329 | debug_blank_line(); | 329 | debug_blank_line(); | |
330 | 330 | |||
331 | state.heading = "token classification"; | 331 | state.heading = "token classification"; | |
332 | debug_ps_enum(prev_lsym, lsym_name); | 332 | debug_ps_enum(prev_lsym, lsym_name); | |
333 | debug_ps_bool(in_stmt_or_decl); | 333 | debug_ps_bool(in_stmt_or_decl); | |
334 | debug_ps_bool(in_decl); | 334 | debug_ps_bool(in_decl); | |
335 | debug_ps_bool(in_var_decl); | 335 | debug_ps_bool(in_var_decl); | |
336 | debug_ps_bool(in_init); | 336 | debug_ps_bool(in_init); | |
337 | debug_ps_int(init_level); | 337 | debug_ps_int(init_level); | |
338 | debug_ps_bool(line_has_func_def); | 338 | debug_ps_bool(line_has_func_def); | |
339 | debug_ps_bool(in_func_def_params); | 339 | debug_ps_bool(in_func_def_params); | |
340 | debug_ps_bool(line_has_decl); | 340 | debug_ps_bool(line_has_decl); | |
341 | debug_ps_enum(lbrace_kind, psym_name); | 341 | debug_ps_enum(lbrace_kind, psym_name); | |
342 | debug_ps_enum(spaced_expr_psym, psym_name); | 342 | debug_ps_enum(spaced_expr_psym, psym_name); | |
343 | debug_ps_bool(seen_case); | 343 | debug_ps_bool(seen_case); | |
344 | debug_ps_bool(prev_paren_was_cast); | 344 | debug_ps_bool(prev_paren_was_cast); | |
345 | debug_ps_int(quest_level); | 345 | debug_ps_int(quest_level); | |
346 | 346 | |||
347 | state.heading = "indentation of statements and declarations"; | 347 | state.heading = "indentation of statements and declarations"; | |
348 | debug_ps_int(ind_level); | 348 | debug_ps_int(ind_level); | |
349 | debug_ps_int(ind_level_follow); | 349 | debug_ps_int(ind_level_follow); | |
350 | debug_ps_bool(in_stmt_cont); | 350 | debug_ps_bool(in_stmt_cont); | |
351 | debug_ps_int(decl_level); | 351 | debug_ps_int(decl_level); | |
352 | debug_ps_di_stack(); | 352 | debug_ps_di_stack(); | |
353 | debug_ps_bool(decl_indent_done); | 353 | debug_ps_bool(decl_indent_done); | |
354 | debug_ps_int(decl_ind); | 354 | debug_ps_int(decl_ind); | |
355 | debug_ps_bool(tabs_to_var); | 355 | debug_ps_bool(tabs_to_var); | |
356 | debug_ps_enum(extra_expr_indent, extra_expr_indent_name); | 356 | debug_ps_enum(extra_expr_indent, extra_expr_indent_name); | |
357 | 357 | |||
358 | // The parser symbol stack is printed in debug_psyms_stack instead. | 358 | // The parser symbol stack is printed in debug_psyms_stack instead. | |
359 | 359 | |||
360 | state.heading = "spacing inside a statement or declaration"; | 360 | state.heading = "spacing inside a statement or declaration"; | |
361 | debug_ps_bool(next_unary); | 361 | debug_ps_bool(next_unary); | |
362 | debug_ps_bool(want_blank); | 362 | debug_ps_bool(want_blank); | |
363 | debug_ps_int(line_start_nparen); | 363 | debug_ps_int(ind_paren_level); | |
364 | debug_ps_int(nparen); | 364 | debug_ps_int(nparen); | |
365 | debug_ps_paren(); | 365 | debug_ps_paren(); | |
366 | 366 | |||
367 | state.heading = "horizontal spacing for comments"; | 367 | state.heading = "horizontal spacing for comments"; | |
368 | debug_ps_int(comment_delta); | 368 | debug_ps_int(comment_delta); | |
369 | debug_ps_int(n_comment_delta); | 369 | debug_ps_int(n_comment_delta); | |
370 | debug_ps_int(com_ind); | 370 | debug_ps_int(com_ind); | |
371 | 371 | |||
372 | state.heading = "vertical spacing"; | 372 | state.heading = "vertical spacing"; | |
373 | debug_ps_bool(break_after_comma); | 373 | debug_ps_bool(break_after_comma); | |
374 | debug_ps_bool(force_nl); | 374 | debug_ps_bool(force_nl); | |
375 | debug_ps_enum(declaration, declaration_name); | 375 | debug_ps_enum(declaration, declaration_name); | |
376 | debug_ps_bool(blank_line_after_decl); | 376 | debug_ps_bool(blank_line_after_decl); | |
377 | 377 | |||
378 | state.heading = "comments"; | 378 | state.heading = "comments"; | |
379 | debug_ps_bool(curr_col_1); | 379 | debug_ps_bool(curr_col_1); | |
380 | debug_ps_bool(next_col_1); | 380 | debug_ps_bool(next_col_1); | |
381 | 381 | |||
382 | state.heading = NULL; | 382 | state.heading = NULL; | |
383 | debug_blank_line(); | 383 | debug_blank_line(); | |
384 | 384 | |||
385 | state.prev_ps = ps; | 385 | state.prev_ps = ps; | |
386 | state.ps_first = false; | 386 | state.ps_first = false; | |
387 | } | 387 | } | |
388 | 388 | |||
389 | void | 389 | void | |
390 | debug_psyms_stack(const char *situation) | 390 | debug_psyms_stack(const char *situation) | |
391 | { | 391 | { | |
392 | debug_printf("parse stack %s:", situation); | 392 | debug_printf("parse stack %s:", situation); | |
393 | const struct psym_stack *psyms = &ps.psyms; | 393 | const struct psym_stack *psyms = &ps.psyms; | |
394 | for (int i = 0; i <= psyms->top; ++i) | 394 | for (int i = 0; i <= psyms->top; ++i) | |
395 | debug_printf(" %d %s", | 395 | debug_printf(" %d %s", | |
396 | psyms->ind_level[i], psym_name[psyms->sym[i]]); | 396 | psyms->ind_level[i], psym_name[psyms->sym[i]]); | |
397 | debug_println(""); | 397 | debug_println(""); | |
398 | } | 398 | } | |
399 | #endif | 399 | #endif |
--- src/usr.bin/indent/indent.c 2023/06/10 20:37:12 1.356
+++ src/usr.bin/indent/indent.c 2023/06/10 21:36:38 1.357
@@ -1,1080 +1,1080 @@ | @@ -1,1080 +1,1080 @@ | |||
1 | /* $NetBSD: indent.c,v 1.356 2023/06/10 20:37:12 rillig Exp $ */ | 1 | /* $NetBSD: indent.c,v 1.357 2023/06/10 21:36:38 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 | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
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.356 2023/06/10 20:37:12 rillig Exp $"); | 41 | __RCSID("$NetBSD: indent.c,v 1.357 2023/06/10 21:36:38 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, | |
55 | .cuddle_else = true, | 55 | .cuddle_else = true, | |
56 | .comment_column = 33, | 56 | .comment_column = 33, | |
57 | .decl_indent = 16, | 57 | .decl_indent = 16, | |
58 | .else_if_in_same_line = true, | 58 | .else_if_in_same_line = true, | |
59 | .function_brace_split = true, | 59 | .function_brace_split = true, | |
60 | .format_col1_comments = true, | 60 | .format_col1_comments = true, | |
61 | .format_block_comments = true, | 61 | .format_block_comments = true, | |
62 | .indent_parameters = true, | 62 | .indent_parameters = true, | |
63 | .indent_size = 8, | 63 | .indent_size = 8, | |
64 | .local_decl_indent = -1, | 64 | .local_decl_indent = -1, | |
65 | .lineup_to_parens = true, | 65 | .lineup_to_parens = true, | |
66 | .procnames_start_line = true, | 66 | .procnames_start_line = true, | |
67 | .star_comment_cont = true, | 67 | .star_comment_cont = true, | |
68 | .tabsize = 8, | 68 | .tabsize = 8, | |
69 | .max_line_length = 78, | 69 | .max_line_length = 78, | |
70 | .use_tabs = true, | 70 | .use_tabs = true, | |
71 | }; | 71 | }; | |
72 | 72 | |||
73 | struct parser_state ps; | 73 | struct parser_state ps; | |
74 | 74 | |||
75 | struct buffer token; | 75 | struct buffer token; | |
76 | 76 | |||
77 | struct buffer lab; | 77 | struct buffer lab; | |
78 | struct buffer code; | 78 | struct buffer code; | |
79 | struct buffer com; | 79 | struct buffer com; | |
80 | 80 | |||
81 | bool found_err; | 81 | bool found_err; | |
82 | bool had_eof; | 82 | bool had_eof; | |
83 | int line_no = 1; | 83 | int line_no = 1; | |
84 | 84 | |||
85 | static int ifdef_level; | 85 | static int ifdef_level; | |
86 | static struct parser_state state_stack[5]; | 86 | static struct parser_state state_stack[5]; | |
87 | 87 | |||
88 | FILE *input; | 88 | FILE *input; | |
89 | FILE *output; | 89 | FILE *output; | |
90 | 90 | |||
91 | static const char *in_name = "Standard Input"; | 91 | static const char *in_name = "Standard Input"; | |
92 | static char backup_name[PATH_MAX]; | 92 | static char backup_name[PATH_MAX]; | |
93 | static const char *backup_suffix = ".BAK"; | 93 | static const char *backup_suffix = ".BAK"; | |
94 | 94 | |||
95 | 95 | |||
96 | void * | 96 | void * | |
97 | nonnull(void *p) | 97 | nonnull(void *p) | |
98 | { | 98 | { | |
99 | if (p == NULL) | 99 | if (p == NULL) | |
100 | err(EXIT_FAILURE, NULL); | 100 | err(EXIT_FAILURE, NULL); | |
101 | return p; | 101 | return p; | |
102 | } | 102 | } | |
103 | 103 | |||
104 | static void | 104 | static void | |
105 | buf_expand(struct buffer *buf, size_t add_size) | 105 | buf_expand(struct buffer *buf, size_t add_size) | |
106 | { | 106 | { | |
107 | buf->cap = buf->cap + add_size + 400; | 107 | buf->cap = buf->cap + add_size + 400; | |
108 | buf->s = nonnull(realloc(buf->s, buf->cap)); | 108 | buf->s = nonnull(realloc(buf->s, buf->cap)); | |
109 | } | 109 | } | |
110 | 110 | |||
111 | #ifdef debug | 111 | #ifdef debug | |
112 | void | 112 | void | |
113 | buf_terminate(struct buffer *buf) | 113 | buf_terminate(struct buffer *buf) | |
114 | { | 114 | { | |
115 | if (buf->len == buf->cap) | 115 | if (buf->len == buf->cap) | |
116 | buf_expand(buf, 1); | 116 | buf_expand(buf, 1); | |
117 | buf->s[buf->len] = '\0'; | 117 | buf->s[buf->len] = '\0'; | |
118 | } | 118 | } | |
119 | #endif | 119 | #endif | |
120 | 120 | |||
121 | void | 121 | void | |
122 | buf_add_char(struct buffer *buf, char ch) | 122 | buf_add_char(struct buffer *buf, char ch) | |
123 | { | 123 | { | |
124 | if (buf->len == buf->cap) | 124 | if (buf->len == buf->cap) | |
125 | buf_expand(buf, 1); | 125 | buf_expand(buf, 1); | |
126 | buf->s[buf->len++] = ch; | 126 | buf->s[buf->len++] = ch; | |
127 | buf_terminate(buf); | 127 | buf_terminate(buf); | |
128 | } | 128 | } | |
129 | 129 | |||
130 | void | 130 | void | |
131 | buf_add_chars(struct buffer *buf, const char *s, size_t len) | 131 | buf_add_chars(struct buffer *buf, const char *s, size_t len) | |
132 | { | 132 | { | |
133 | if (len == 0) | 133 | if (len == 0) | |
134 | return; | 134 | return; | |
135 | if (len > buf->cap - buf->len) | 135 | if (len > buf->cap - buf->len) | |
136 | buf_expand(buf, len); | 136 | buf_expand(buf, len); | |
137 | memcpy(buf->s + buf->len, s, len); | 137 | memcpy(buf->s + buf->len, s, len); | |
138 | buf->len += len; | 138 | buf->len += len; | |
139 | buf_terminate(buf); | 139 | buf_terminate(buf); | |
140 | } | 140 | } | |
141 | 141 | |||
142 | static void | 142 | static void | |
143 | buf_add_buf(struct buffer *buf, const struct buffer *add) | 143 | buf_add_buf(struct buffer *buf, const struct buffer *add) | |
144 | { | 144 | { | |
145 | buf_add_chars(buf, add->s, add->len); | 145 | buf_add_chars(buf, add->s, add->len); | |
146 | } | 146 | } | |
147 | 147 | |||
148 | void | 148 | void | |
149 | diag(int level, const char *msg, ...) | 149 | diag(int level, const char *msg, ...) | |
150 | { | 150 | { | |
151 | va_list ap; | 151 | va_list ap; | |
152 | 152 | |||
153 | if (level != 0) | 153 | if (level != 0) | |
154 | found_err = true; | 154 | found_err = true; | |
155 | 155 | |||
156 | va_start(ap, msg); | 156 | va_start(ap, msg); | |
157 | fprintf(stderr, "%s: %s:%d: ", | 157 | fprintf(stderr, "%s: %s:%d: ", | |
158 | level == 0 ? "warning" : "error", in_name, line_no); | 158 | level == 0 ? "warning" : "error", in_name, line_no); | |
159 | vfprintf(stderr, msg, ap); | 159 | vfprintf(stderr, msg, ap); | |
160 | fprintf(stderr, "\n"); | 160 | fprintf(stderr, "\n"); | |
161 | va_end(ap); | 161 | va_end(ap); | |
162 | } | 162 | } | |
163 | 163 | |||
164 | /* | 164 | /* | |
165 | * Compute the indentation from starting at 'ind' and adding the text starting | 165 | * Compute the indentation from starting at 'ind' and adding the text starting | |
166 | * at 's'. | 166 | * at 's'. | |
167 | */ | 167 | */ | |
168 | int | 168 | int | |
169 | ind_add(int ind, const char *s, size_t len) | 169 | ind_add(int ind, const char *s, size_t len) | |
170 | { | 170 | { | |
171 | for (const char *p = s; len > 0; p++, len--) { | 171 | for (const char *p = s; len > 0; p++, len--) { | |
172 | if (*p == '\n') | 172 | if (*p == '\n') | |
173 | ind = 0; | 173 | ind = 0; | |
174 | else if (*p == '\t') | 174 | else if (*p == '\t') | |
175 | ind = next_tab(ind); | 175 | ind = next_tab(ind); | |
176 | else if (*p == '\b') | 176 | else if (*p == '\b') | |
177 | --ind; | 177 | --ind; | |
178 | else | 178 | else | |
179 | ++ind; | 179 | ++ind; | |
180 | } | 180 | } | |
181 | return ind; | 181 | return ind; | |
182 | } | 182 | } | |
183 | 183 | |||
184 | static void | 184 | static void | |
185 | init_globals(void) | 185 | init_globals(void) | |
186 | { | 186 | { | |
187 | ps.psyms.sym[0] = psym_stmt_list; | 187 | ps.psyms.sym[0] = psym_stmt_list; | |
188 | ps.prev_lsym = lsym_semicolon; | 188 | ps.prev_lsym = lsym_semicolon; | |
189 | ps.next_col_1 = true; | 189 | ps.next_col_1 = true; | |
190 | ps.lbrace_kind = psym_lbrace_block; | 190 | ps.lbrace_kind = psym_lbrace_block; | |
191 | 191 | |||
192 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | 192 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | |
193 | if (suffix != NULL) | 193 | if (suffix != NULL) | |
194 | backup_suffix = suffix; | 194 | backup_suffix = suffix; | |
195 | } | 195 | } | |
196 | 196 | |||
197 | static void | 197 | static void | |
198 | load_profiles(int argc, char **argv) | 198 | load_profiles(int argc, char **argv) | |
199 | { | 199 | { | |
200 | const char *profile_name = NULL; | 200 | const char *profile_name = NULL; | |
201 | 201 | |||
202 | for (int i = 1; i < argc; ++i) { | 202 | for (int i = 1; i < argc; ++i) { | |
203 | const char *arg = argv[i]; | 203 | const char *arg = argv[i]; | |
204 | 204 | |||
205 | if (strcmp(arg, "-npro") == 0) | 205 | if (strcmp(arg, "-npro") == 0) | |
206 | return; | 206 | return; | |
207 | if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0') | 207 | if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0') | |
208 | profile_name = arg + 2; | 208 | profile_name = arg + 2; | |
209 | } | 209 | } | |
210 | 210 | |||
211 | load_profile_files(profile_name); | 211 | load_profile_files(profile_name); | |
212 | } | 212 | } | |
213 | 213 | |||
214 | /* | 214 | /* | |
215 | * Copy the input file to the backup file, then make the backup file the input | 215 | * Copy the input file to the backup file, then make the backup file the input | |
216 | * and the original input file the output. | 216 | * and the original input file the output. | |
217 | */ | 217 | */ | |
218 | static void | 218 | static void | |
219 | copy_to_bak_file(void) | 219 | copy_to_bak_file(void) | |
220 | { | 220 | { | |
221 | size_t n; | 221 | size_t n; | |
222 | char buff[BUFSIZ]; | 222 | char buff[BUFSIZ]; | |
223 | 223 | |||
224 | const char *last_slash = strrchr(in_name, '/'); | 224 | const char *last_slash = strrchr(in_name, '/'); | |
225 | const char *base = last_slash != NULL ? last_slash + 1 : in_name; | 225 | const char *base = last_slash != NULL ? last_slash + 1 : in_name; | |
226 | snprintf(backup_name, sizeof(backup_name), "%s%s", base, backup_suffix); | 226 | snprintf(backup_name, sizeof(backup_name), "%s%s", base, backup_suffix); | |
227 | 227 | |||
228 | /* copy the input file to the backup file */ | 228 | /* copy the input file to the backup file */ | |
229 | FILE *bak = fopen(backup_name, "w"); | 229 | FILE *bak = fopen(backup_name, "w"); | |
230 | if (bak == NULL) | 230 | if (bak == NULL) | |
231 | err(1, "%s", backup_name); | 231 | err(1, "%s", backup_name); | |
232 | 232 | |||
233 | while ((n = fread(buff, 1, sizeof(buff), input)) > 0) | 233 | while ((n = fread(buff, 1, sizeof(buff), input)) > 0) | |
234 | if (fwrite(buff, 1, n, bak) != n) | 234 | if (fwrite(buff, 1, n, bak) != n) | |
235 | err(1, "%s", backup_name); | 235 | err(1, "%s", backup_name); | |
236 | if (fclose(input) != 0) | 236 | if (fclose(input) != 0) | |
237 | err(1, "%s", in_name); | 237 | err(1, "%s", in_name); | |
238 | if (fclose(bak) != 0) | 238 | if (fclose(bak) != 0) | |
239 | err(1, "%s", backup_name); | 239 | err(1, "%s", backup_name); | |
240 | 240 | |||
241 | /* re-open the backup file as the input file */ | 241 | /* re-open the backup file as the input file */ | |
242 | input = fopen(backup_name, "r"); | 242 | input = fopen(backup_name, "r"); | |
243 | if (input == NULL) | 243 | if (input == NULL) | |
244 | err(1, "%s", backup_name); | 244 | err(1, "%s", backup_name); | |
245 | /* now the original input file will be the output */ | 245 | /* now the original input file will be the output */ | |
246 | output = fopen(in_name, "w"); | 246 | output = fopen(in_name, "w"); | |
247 | if (output == NULL) { | 247 | if (output == NULL) { | |
248 | remove(backup_name); | 248 | remove(backup_name); | |
249 | err(1, "%s", in_name); | 249 | err(1, "%s", in_name); | |
250 | } | 250 | } | |
251 | } | 251 | } | |
252 | 252 | |||
253 | static void | 253 | static void | |
254 | parse_command_line(int argc, char **argv) | 254 | parse_command_line(int argc, char **argv) | |
255 | { | 255 | { | |
256 | for (int i = 1; i < argc; ++i) { | 256 | for (int i = 1; i < argc; ++i) { | |
257 | const char *arg = argv[i]; | 257 | const char *arg = argv[i]; | |
258 | 258 | |||
259 | if (arg[0] == '-') { | 259 | if (arg[0] == '-') { | |
260 | set_option(arg, "Command line"); | 260 | set_option(arg, "Command line"); | |
261 | 261 | |||
262 | } else if (input == NULL) { | 262 | } else if (input == NULL) { | |
263 | in_name = arg; | 263 | in_name = arg; | |
264 | if ((input = fopen(in_name, "r")) == NULL) | 264 | if ((input = fopen(in_name, "r")) == NULL) | |
265 | err(1, "%s", in_name); | 265 | err(1, "%s", in_name); | |
266 | 266 | |||
267 | } else if (output == NULL) { | 267 | } else if (output == NULL) { | |
268 | if (strcmp(arg, in_name) == 0) | 268 | if (strcmp(arg, in_name) == 0) | |
269 | errx(1, "input and output files " | 269 | errx(1, "input and output files " | |
270 | "must be different"); | 270 | "must be different"); | |
271 | if ((output = fopen(arg, "w")) == NULL) | 271 | if ((output = fopen(arg, "w")) == NULL) | |
272 | err(1, "%s", arg); | 272 | err(1, "%s", arg); | |
273 | 273 | |||
274 | } else | 274 | } else | |
275 | errx(1, "too many arguments: %s", arg); | 275 | errx(1, "too many arguments: %s", arg); | |
276 | } | 276 | } | |
277 | 277 | |||
278 | if (input == NULL) { | 278 | if (input == NULL) { | |
279 | input = stdin; | 279 | input = stdin; | |
280 | output = stdout; | 280 | output = stdout; | |
281 | } else if (output == NULL) | 281 | } else if (output == NULL) | |
282 | copy_to_bak_file(); | 282 | copy_to_bak_file(); | |
283 | 283 | |||
284 | if (opt.comment_column <= 1) | 284 | if (opt.comment_column <= 1) | |
285 | opt.comment_column = 2; /* don't put normal comments in column | 285 | opt.comment_column = 2; /* don't put normal comments in column | |
286 | * 1, see opt.format_col1_comments */ | 286 | * 1, see opt.format_col1_comments */ | |
287 | if (opt.block_comment_max_line_length <= 0) | 287 | if (opt.block_comment_max_line_length <= 0) | |
288 | opt.block_comment_max_line_length = opt.max_line_length; | 288 | opt.block_comment_max_line_length = opt.max_line_length; | |
289 | if (opt.local_decl_indent < 0) | 289 | if (opt.local_decl_indent < 0) | |
290 | opt.local_decl_indent = opt.decl_indent; | 290 | opt.local_decl_indent = opt.decl_indent; | |
291 | if (opt.decl_comment_column <= 0) | 291 | if (opt.decl_comment_column <= 0) | |
292 | opt.decl_comment_column = opt.left_justify_decl | 292 | opt.decl_comment_column = opt.left_justify_decl | |
293 | ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) | 293 | ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) | |
294 | : opt.comment_column; | 294 | : opt.comment_column; | |
295 | if (opt.continuation_indent == 0) | 295 | if (opt.continuation_indent == 0) | |
296 | opt.continuation_indent = opt.indent_size; | 296 | opt.continuation_indent = opt.indent_size; | |
297 | } | 297 | } | |
298 | 298 | |||
299 | static void | 299 | static void | |
300 | set_initial_indentation(void) | 300 | set_initial_indentation(void) | |
301 | { | 301 | { | |
302 | inp_read_line(); | 302 | inp_read_line(); | |
303 | 303 | |||
304 | int ind = 0; | 304 | int ind = 0; | |
305 | for (const char *p = inp_p;; p++) { | 305 | for (const char *p = inp_p;; p++) { | |
306 | if (*p == ' ') | 306 | if (*p == ' ') | |
307 | ind++; | 307 | ind++; | |
308 | else if (*p == '\t') | 308 | else if (*p == '\t') | |
309 | ind = next_tab(ind); | 309 | ind = next_tab(ind); | |
310 | else | 310 | else | |
311 | break; | 311 | break; | |
312 | } | 312 | } | |
313 | 313 | |||
314 | ps.ind_level = ps.ind_level_follow = ind / opt.indent_size; | 314 | ps.ind_level = ps.ind_level_follow = ind / opt.indent_size; | |
315 | } | 315 | } | |
316 | 316 | |||
317 | static bool | 317 | static bool | |
318 | should_break_line(lexer_symbol lsym) | 318 | should_break_line(lexer_symbol lsym) | |
319 | { | 319 | { | |
320 | if (lsym == lsym_semicolon) | 320 | if (lsym == lsym_semicolon) | |
321 | return false; | 321 | return false; | |
322 | if (ps.prev_lsym == lsym_lbrace || ps.prev_lsym == lsym_semicolon) | 322 | if (ps.prev_lsym == lsym_lbrace || ps.prev_lsym == lsym_semicolon) | |
323 | return true; | 323 | return true; | |
324 | if (lsym == lsym_lbrace && opt.brace_same_line) | 324 | if (lsym == lsym_lbrace && opt.brace_same_line) | |
325 | return false; | 325 | return false; | |
326 | return true; | 326 | return true; | |
327 | } | 327 | } | |
328 | 328 | |||
329 | static void | 329 | static void | |
330 | move_com_to_code(lexer_symbol lsym) | 330 | move_com_to_code(lexer_symbol lsym) | |
331 | { | 331 | { | |
332 | if (ps.want_blank) | 332 | if (ps.want_blank) | |
333 | buf_add_char(&code, ' '); | 333 | buf_add_char(&code, ' '); | |
334 | buf_add_buf(&code, &com); | 334 | buf_add_buf(&code, &com); | |
335 | buf_clear(&com); | 335 | buf_clear(&com); | |
336 | ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; | 336 | ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; | |
337 | } | 337 | } | |
338 | 338 | |||
339 | static void | 339 | static void | |
340 | update_ps_lbrace_kind(lexer_symbol lsym) | 340 | update_ps_lbrace_kind(lexer_symbol lsym) | |
341 | { | 341 | { | |
342 | if (lsym == lsym_tag) { | 342 | if (lsym == lsym_tag) { | |
343 | ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : | 343 | ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : | |
344 | token.s[0] == 'u' ? psym_lbrace_union : | 344 | token.s[0] == 'u' ? psym_lbrace_union : | |
345 | psym_lbrace_enum; | 345 | psym_lbrace_enum; | |
346 | } else if (lsym != lsym_type_outside_parentheses | 346 | } else if (lsym != lsym_type_outside_parentheses | |
347 | && lsym != lsym_word | 347 | && lsym != lsym_word | |
348 | && lsym != lsym_lbrace) | 348 | && lsym != lsym_lbrace) | |
349 | ps.lbrace_kind = psym_lbrace_block; | 349 | ps.lbrace_kind = psym_lbrace_block; | |
350 | } | 350 | } | |
351 | 351 | |||
352 | static void | 352 | static void | |
353 | indent_declarator(int decl_ind, bool tabs_to_var) | 353 | indent_declarator(int decl_ind, bool tabs_to_var) | |
354 | { | 354 | { | |
355 | int base = ps.ind_level * opt.indent_size; | 355 | int base = ps.ind_level * opt.indent_size; | |
356 | int ind = base + (int)code.len; | 356 | int ind = base + (int)code.len; | |
357 | int target = base + decl_ind; | 357 | int target = base + decl_ind; | |
358 | size_t orig_code_len = code.len; | 358 | size_t orig_code_len = code.len; | |
359 | 359 | |||
360 | if (tabs_to_var) | 360 | if (tabs_to_var) | |
361 | for (int next; (next = next_tab(ind)) <= target; ind = next) | 361 | for (int next; (next = next_tab(ind)) <= target; ind = next) | |
362 | buf_add_char(&code, '\t'); | 362 | buf_add_char(&code, '\t'); | |
363 | 363 | |||
364 | for (; ind < target; ind++) | 364 | for (; ind < target; ind++) | |
365 | buf_add_char(&code, ' '); | 365 | buf_add_char(&code, ' '); | |
366 | 366 | |||
367 | if (code.len == orig_code_len && ps.want_blank) { | 367 | if (code.len == orig_code_len && ps.want_blank) { | |
368 | buf_add_char(&code, ' '); | 368 | buf_add_char(&code, ' '); | |
369 | ps.want_blank = false; | 369 | ps.want_blank = false; | |
370 | } | 370 | } | |
371 | ps.decl_indent_done = true; | 371 | ps.decl_indent_done = true; | |
372 | } | 372 | } | |
373 | 373 | |||
374 | static bool | 374 | static bool | |
375 | is_function_pointer_declaration(void) | 375 | is_function_pointer_declaration(void) | |
376 | { | 376 | { | |
377 | return ps.in_decl | 377 | return ps.in_decl | |
378 | && !ps.in_init | 378 | && !ps.in_init | |
379 | && !ps.decl_indent_done | 379 | && !ps.decl_indent_done | |
380 | && !ps.line_has_func_def | 380 | && !ps.line_has_func_def | |
381 | && ps.line_start_nparen == 0; | 381 | && ps.ind_paren_level == 0; | |
382 | } | 382 | } | |
383 | 383 | |||
384 | static int | 384 | static int | |
385 | process_eof(void) | 385 | process_eof(void) | |
386 | { | 386 | { | |
387 | finish_output(); | 387 | finish_output(); | |
388 | 388 | |||
389 | if (ps.psyms.top > 1) /* check for balanced braces */ | 389 | if (ps.psyms.top > 1) /* check for balanced braces */ | |
390 | diag(1, "Stuff missing from end of file"); | 390 | diag(1, "Stuff missing from end of file"); | |
391 | 391 | |||
392 | return found_err ? EXIT_FAILURE : EXIT_SUCCESS; | 392 | return found_err ? EXIT_FAILURE : EXIT_SUCCESS; | |
393 | } | 393 | } | |
394 | 394 | |||
395 | /* move the whole line to the 'label' buffer */ | 395 | /* move the whole line to the 'label' buffer */ | |
396 | static void | 396 | static void | |
397 | read_preprocessing_line(void) | 397 | read_preprocessing_line(void) | |
398 | { | 398 | { | |
399 | enum { | 399 | enum { | |
400 | PLAIN, STR, CHR, COMM | 400 | PLAIN, STR, CHR, COMM | |
401 | } state = PLAIN; | 401 | } state = PLAIN; | |
402 | 402 | |||
403 | buf_add_char(&lab, '#'); | 403 | buf_add_char(&lab, '#'); | |
404 | 404 | |||
405 | while (inp_p[0] != '\n' || (state == COMM && !had_eof)) { | 405 | while (inp_p[0] != '\n' || (state == COMM && !had_eof)) { | |
406 | buf_add_char(&lab, inp_next()); | 406 | buf_add_char(&lab, inp_next()); | |
407 | switch (lab.s[lab.len - 1]) { | 407 | switch (lab.s[lab.len - 1]) { | |
408 | case '\\': | 408 | case '\\': | |
409 | if (state != COMM) | 409 | if (state != COMM) | |
410 | buf_add_char(&lab, inp_next()); | 410 | buf_add_char(&lab, inp_next()); | |
411 | break; | 411 | break; | |
412 | case '/': | 412 | case '/': | |
413 | if (inp_p[0] == '*' && state == PLAIN) { | 413 | if (inp_p[0] == '*' && state == PLAIN) { | |
414 | state = COMM; | 414 | state = COMM; | |
415 | buf_add_char(&lab, *inp_p++); | 415 | buf_add_char(&lab, *inp_p++); | |
416 | } | 416 | } | |
417 | break; | 417 | break; | |
418 | case '"': | 418 | case '"': | |
419 | if (state == STR) | 419 | if (state == STR) | |
420 | state = PLAIN; | 420 | state = PLAIN; | |
421 | else if (state == PLAIN) | 421 | else if (state == PLAIN) | |
422 | state = STR; | 422 | state = STR; | |
423 | break; | 423 | break; | |
424 | case '\'': | 424 | case '\'': | |
425 | if (state == CHR) | 425 | if (state == CHR) | |
426 | state = PLAIN; | 426 | state = PLAIN; | |
427 | else if (state == PLAIN) | 427 | else if (state == PLAIN) | |
428 | state = CHR; | 428 | state = CHR; | |
429 | break; | 429 | break; | |
430 | case '*': | 430 | case '*': | |
431 | if (inp_p[0] == '/' && state == COMM) { | 431 | if (inp_p[0] == '/' && state == COMM) { | |
432 | state = PLAIN; | 432 | state = PLAIN; | |
433 | buf_add_char(&lab, *inp_p++); | 433 | buf_add_char(&lab, *inp_p++); | |
434 | } | 434 | } | |
435 | break; | 435 | break; | |
436 | } | 436 | } | |
437 | } | 437 | } | |
438 | 438 | |||
439 | while (lab.len > 0 && ch_isblank(lab.s[lab.len - 1])) | 439 | while (lab.len > 0 && ch_isblank(lab.s[lab.len - 1])) | |
440 | lab.len--; | 440 | lab.len--; | |
441 | buf_terminate(&lab); | 441 | buf_terminate(&lab); | |
442 | } | 442 | } | |
443 | 443 | |||
444 | static void | 444 | static void | |
445 | process_preprocessing(void) | 445 | process_preprocessing(void) | |
446 | { | 446 | { | |
447 | if (lab.len > 0 || code.len > 0 || com.len > 0) | 447 | if (lab.len > 0 || code.len > 0 || com.len > 0) | |
448 | output_line(); | 448 | output_line(); | |
449 | 449 | |||
450 | read_preprocessing_line(); | 450 | read_preprocessing_line(); | |
451 | 451 | |||
452 | const char *dir = lab.s + 1, *line_end = lab.s + lab.len; | 452 | const char *dir = lab.s + 1, *line_end = lab.s + lab.len; | |
453 | while (dir < line_end && ch_isblank(*dir)) | 453 | while (dir < line_end && ch_isblank(*dir)) | |
454 | dir++; | 454 | dir++; | |
455 | size_t dir_len = 0; | 455 | size_t dir_len = 0; | |
456 | while (dir + dir_len < line_end && ch_isalpha(dir[dir_len])) | 456 | while (dir + dir_len < line_end && ch_isalpha(dir[dir_len])) | |
457 | dir_len++; | 457 | dir_len++; | |
458 | 458 | |||
459 | if (dir_len >= 2 && memcmp(dir, "if", 2) == 0) { | 459 | if (dir_len >= 2 && memcmp(dir, "if", 2) == 0) { | |
460 | if ((size_t)ifdef_level < array_length(state_stack)) | 460 | if ((size_t)ifdef_level < array_length(state_stack)) | |
461 | state_stack[ifdef_level++] = ps; | 461 | state_stack[ifdef_level++] = ps; | |
462 | else | 462 | else | |
463 | diag(1, "#if stack overflow"); | 463 | diag(1, "#if stack overflow"); | |
464 | out.line_kind = lk_if; | 464 | out.line_kind = lk_if; | |
465 | 465 | |||
466 | } else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) { | 466 | } else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) { | |
467 | if (ifdef_level <= 0) | 467 | if (ifdef_level <= 0) | |
468 | diag(1, dir[2] == 'i' | 468 | diag(1, dir[2] == 'i' | |
469 | ? "Unmatched #elif" : "Unmatched #else"); | 469 | ? "Unmatched #elif" : "Unmatched #else"); | |
470 | else | 470 | else | |
471 | ps = state_stack[ifdef_level - 1]; | 471 | ps = state_stack[ifdef_level - 1]; | |
472 | 472 | |||
473 | } else if (dir_len == 5 && memcmp(dir, "endif", 5) == 0) { | 473 | } else if (dir_len == 5 && memcmp(dir, "endif", 5) == 0) { | |
474 | if (ifdef_level <= 0) | 474 | if (ifdef_level <= 0) | |
475 | diag(1, "Unmatched #endif"); | 475 | diag(1, "Unmatched #endif"); | |
476 | else | 476 | else | |
477 | ifdef_level--; | 477 | ifdef_level--; | |
478 | out.line_kind = lk_endif; | 478 | out.line_kind = lk_endif; | |
479 | } | 479 | } | |
480 | } | 480 | } | |
481 | 481 | |||
482 | static void | 482 | static void | |
483 | process_newline(void) | 483 | process_newline(void) | |
484 | { | 484 | { | |
485 | if (ps.prev_lsym == lsym_comma | 485 | if (ps.prev_lsym == lsym_comma | |
486 | && ps.nparen == 0 && !ps.in_init | 486 | && ps.nparen == 0 && !ps.in_init | |
487 | && !opt.break_after_comma && ps.break_after_comma | 487 | && !opt.break_after_comma && ps.break_after_comma | |
488 | && lab.len == 0 /* for preprocessing lines */ | 488 | && lab.len == 0 /* for preprocessing lines */ | |
489 | && com.len == 0) | 489 | && com.len == 0) | |
490 | goto stay_in_line; | 490 | goto stay_in_line; | |
491 | if (ps.psyms.sym[ps.psyms.top] == psym_switch_expr | 491 | if (ps.psyms.sym[ps.psyms.top] == psym_switch_expr | |
492 | && opt.brace_same_line) { | 492 | && opt.brace_same_line) { | |
493 | ps.force_nl = true; | 493 | ps.force_nl = true; | |
494 | goto stay_in_line; | 494 | goto stay_in_line; | |
495 | } | 495 | } | |
496 | 496 | |||
497 | output_line(); | 497 | output_line(); | |
498 | 498 | |||
499 | stay_in_line: | 499 | stay_in_line: | |
500 | ++line_no; | 500 | ++line_no; | |
501 | } | 501 | } | |
502 | 502 | |||
503 | static bool | 503 | static bool | |
504 | want_blank_before_lparen(void) | 504 | want_blank_before_lparen(void) | |
505 | { | 505 | { | |
506 | if (!ps.want_blank) | 506 | if (!ps.want_blank) | |
507 | return false; | 507 | return false; | |
508 | if (opt.proc_calls_space) | 508 | if (opt.proc_calls_space) | |
509 | return true; | 509 | return true; | |
510 | if (ps.prev_lsym == lsym_rparen || ps.prev_lsym == lsym_rbracket) | 510 | if (ps.prev_lsym == lsym_rparen || ps.prev_lsym == lsym_rbracket) | |
511 | return false; | 511 | return false; | |
512 | if (ps.prev_lsym == lsym_offsetof) | 512 | if (ps.prev_lsym == lsym_offsetof) | |
513 | return false; | 513 | return false; | |
514 | if (ps.prev_lsym == lsym_sizeof) | 514 | if (ps.prev_lsym == lsym_sizeof) | |
515 | return opt.blank_after_sizeof; | 515 | return opt.blank_after_sizeof; | |
516 | if (ps.prev_lsym == lsym_word || ps.prev_lsym == lsym_funcname) | 516 | if (ps.prev_lsym == lsym_word || ps.prev_lsym == lsym_funcname) | |
517 | return false; | 517 | return false; | |
518 | return true; | 518 | return true; | |
519 | } | 519 | } | |
520 | 520 | |||
521 | static void | 521 | static void | |
522 | process_lparen(void) | 522 | process_lparen(void) | |
523 | { | 523 | { | |
524 | if (++ps.nparen == array_length(ps.paren)) { | 524 | if (++ps.nparen == array_length(ps.paren)) { | |
525 | diag(0, "Reached internal limit of %zu unclosed parentheses", | 525 | diag(0, "Reached internal limit of %zu unclosed parentheses", | |
526 | array_length(ps.paren)); | 526 | array_length(ps.paren)); | |
527 | ps.nparen--; | 527 | ps.nparen--; | |
528 | } | 528 | } | |
529 | 529 | |||
530 | if (is_function_pointer_declaration()) | 530 | if (is_function_pointer_declaration()) | |
531 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | 531 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | |
532 | else if (want_blank_before_lparen()) | 532 | else if (want_blank_before_lparen()) | |
533 | buf_add_char(&code, ' '); | 533 | buf_add_char(&code, ' '); | |
534 | ps.want_blank = false; | 534 | ps.want_blank = false; | |
535 | buf_add_char(&code, token.s[0]); | 535 | buf_add_char(&code, token.s[0]); | |
536 | 536 | |||
537 | if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) | 537 | if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) | |
538 | ps.extra_expr_indent = eei_maybe; | 538 | ps.extra_expr_indent = eei_maybe; | |
539 | 539 | |||
540 | if (ps.in_var_decl && ps.psyms.top <= 2 && !ps.in_init) { | 540 | if (ps.in_var_decl && ps.psyms.top <= 2 && !ps.in_init) { | |
541 | parse(psym_stmt); /* prepare for function definition */ | 541 | parse(psym_stmt); /* prepare for function definition */ | |
542 | ps.in_var_decl = false; | 542 | ps.in_var_decl = false; | |
543 | } | 543 | } | |
544 | 544 | |||
545 | int indent = ind_add(0, code.s, code.len); | 545 | int indent = ind_add(0, code.s, code.len); | |
546 | 546 | |||
547 | enum paren_level_cast cast = cast_unknown; | 547 | enum paren_level_cast cast = cast_unknown; | |
548 | if (ps.prev_lsym == lsym_offsetof | 548 | if (ps.prev_lsym == lsym_offsetof | |
549 | || ps.prev_lsym == lsym_sizeof | 549 | || ps.prev_lsym == lsym_sizeof | |
550 | || ps.prev_lsym == lsym_for | 550 | || ps.prev_lsym == lsym_for | |
551 | || ps.prev_lsym == lsym_if | 551 | || ps.prev_lsym == lsym_if | |
552 | || ps.prev_lsym == lsym_switch | 552 | || ps.prev_lsym == lsym_switch | |
553 | || ps.prev_lsym == lsym_while | 553 | || ps.prev_lsym == lsym_while | |
554 | || ps.line_has_func_def) | 554 | || ps.line_has_func_def) | |
555 | cast = cast_no; | 555 | cast = cast_no; | |
556 | 556 | |||
557 | ps.paren[ps.nparen - 1].indent = indent; | 557 | ps.paren[ps.nparen - 1].indent = indent; | |
558 | ps.paren[ps.nparen - 1].cast = cast; | 558 | ps.paren[ps.nparen - 1].cast = cast; | |
559 | debug_println("paren_indents[%d] is now %s%d", | 559 | debug_println("paren_indents[%d] is now %s%d", | |
560 | ps.nparen - 1, paren_level_cast_name[cast], indent); | 560 | ps.nparen - 1, paren_level_cast_name[cast], indent); | |
561 | } | 561 | } | |
562 | 562 | |||
563 | static void | 563 | static void | |
564 | process_rparen(void) | 564 | process_rparen(void) | |
565 | { | 565 | { | |
566 | if (ps.nparen == 0) { | 566 | if (ps.nparen == 0) { | |
567 | diag(0, "Extra '%c'", *token.s); | 567 | diag(0, "Extra '%c'", *token.s); | |
568 | goto unbalanced; | 568 | goto unbalanced; | |
569 | } | 569 | } | |
570 | 570 | |||
571 | enum paren_level_cast cast = ps.paren[--ps.nparen].cast; | 571 | enum paren_level_cast cast = ps.paren[--ps.nparen].cast; | |
572 | if (ps.in_func_def_params || (ps.line_has_decl && !ps.in_init)) | 572 | if (ps.in_func_def_params || (ps.line_has_decl && !ps.in_init)) | |
573 | cast = cast_no; | 573 | cast = cast_no; | |
574 | 574 | |||
575 | ps.prev_paren_was_cast = cast == cast_maybe; | 575 | ps.prev_paren_was_cast = cast == cast_maybe; | |
576 | if (cast == cast_maybe) { | 576 | if (cast == cast_maybe) { | |
577 | ps.next_unary = true; | 577 | ps.next_unary = true; | |
578 | ps.want_blank = opt.space_after_cast; | 578 | ps.want_blank = opt.space_after_cast; | |
579 | } else | 579 | } else | |
580 | ps.want_blank = true; | 580 | ps.want_blank = true; | |
581 | 581 | |||
582 | if (code.len == 0) | 582 | if (code.len == 0) | |
583 | ps.line_start_nparen = ps.nparen; | 583 | ps.ind_paren_level = ps.nparen; | |
584 | 584 | |||
585 | unbalanced: | 585 | unbalanced: | |
586 | buf_add_char(&code, token.s[0]); | 586 | buf_add_char(&code, token.s[0]); | |
587 | 587 | |||
588 | if (ps.spaced_expr_psym != psym_0 && ps.nparen == 0) { | 588 | if (ps.spaced_expr_psym != psym_0 && ps.nparen == 0) { | |
589 | if (ps.extra_expr_indent == eei_maybe) | 589 | if (ps.extra_expr_indent == eei_maybe) | |
590 | ps.extra_expr_indent = eei_last; | 590 | ps.extra_expr_indent = eei_last; | |
591 | ps.force_nl = true; | 591 | ps.force_nl = true; | |
592 | ps.next_unary = true; | 592 | ps.next_unary = true; | |
593 | ps.in_stmt_or_decl = false; | 593 | ps.in_stmt_or_decl = false; | |
594 | parse(ps.spaced_expr_psym); | 594 | parse(ps.spaced_expr_psym); | |
595 | ps.spaced_expr_psym = psym_0; | 595 | ps.spaced_expr_psym = psym_0; | |
596 | ps.want_blank = true; | 596 | ps.want_blank = true; | |
597 | out.line_kind = lk_stmt_head; | 597 | out.line_kind = lk_stmt_head; | |
598 | } | 598 | } | |
599 | } | 599 | } | |
600 | 600 | |||
601 | static void | 601 | static void | |
602 | process_lbracket(void) | 602 | process_lbracket(void) | |
603 | { | 603 | { | |
604 | if (++ps.nparen == array_length(ps.paren)) { | 604 | if (++ps.nparen == array_length(ps.paren)) { | |
605 | diag(0, "Reached internal limit of %zu unclosed parentheses", | 605 | diag(0, "Reached internal limit of %zu unclosed parentheses", | |
606 | array_length(ps.paren)); | 606 | array_length(ps.paren)); | |
607 | ps.nparen--; | 607 | ps.nparen--; | |
608 | } | 608 | } | |
609 | 609 | |||
610 | if (code.len > 0 | 610 | if (code.len > 0 | |
611 | && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) | 611 | && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) | |
612 | buf_add_char(&code, ' '); | 612 | buf_add_char(&code, ' '); | |
613 | ps.want_blank = false; | 613 | ps.want_blank = false; | |
614 | buf_add_char(&code, token.s[0]); | 614 | buf_add_char(&code, token.s[0]); | |
615 | 615 | |||
616 | int indent = ind_add(0, code.s, code.len); | 616 | int indent = ind_add(0, code.s, code.len); | |
617 | 617 | |||
618 | ps.paren[ps.nparen - 1].indent = indent; | 618 | ps.paren[ps.nparen - 1].indent = indent; | |
619 | ps.paren[ps.nparen - 1].cast = cast_no; | 619 | ps.paren[ps.nparen - 1].cast = cast_no; | |
620 | debug_println("paren_indents[%d] is now %d", ps.nparen - 1, indent); | 620 | debug_println("paren_indents[%d] is now %d", ps.nparen - 1, indent); | |
621 | } | 621 | } | |
622 | 622 | |||
623 | static void | 623 | static void | |
624 | process_rbracket(void) | 624 | process_rbracket(void) | |
625 | { | 625 | { | |
626 | if (ps.nparen == 0) { | 626 | if (ps.nparen == 0) { | |
627 | diag(0, "Extra '%c'", *token.s); | 627 | diag(0, "Extra '%c'", *token.s); | |
628 | goto unbalanced; | 628 | goto unbalanced; | |
629 | } | 629 | } | |
630 | --ps.nparen; | 630 | --ps.nparen; | |
631 | 631 | |||
632 | ps.want_blank = true; | 632 | ps.want_blank = true; | |
633 | if (code.len == 0) | 633 | if (code.len == 0) | |
634 | ps.line_start_nparen = ps.nparen; | 634 | ps.ind_paren_level = ps.nparen; | |
635 | 635 | |||
636 | unbalanced: | 636 | unbalanced: | |
637 | buf_add_char(&code, token.s[0]); | 637 | buf_add_char(&code, token.s[0]); | |
638 | } | 638 | } | |
639 | 639 | |||
640 | static void | 640 | static void | |
641 | process_lbrace(void) | 641 | process_lbrace(void) | |
642 | { | 642 | { | |
643 | if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { | 643 | if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { | |
644 | ps.in_var_decl = true; // XXX: not really | 644 | ps.in_var_decl = true; // XXX: not really | |
645 | ps.in_init = true; | 645 | ps.in_init = true; | |
646 | } | 646 | } | |
647 | 647 | |||
648 | if (out.line_kind == lk_stmt_head) | 648 | if (out.line_kind == lk_stmt_head) | |
649 | out.line_kind = lk_other; | 649 | out.line_kind = lk_other; | |
650 | 650 | |||
651 | ps.in_stmt_or_decl = false; /* don't indent the {} */ | 651 | ps.in_stmt_or_decl = false; /* don't indent the {} */ | |
652 | 652 | |||
653 | if (ps.in_init) | 653 | if (ps.in_init) | |
654 | ps.init_level++; | 654 | ps.init_level++; | |
655 | else | 655 | else | |
656 | ps.force_nl = true; | 656 | ps.force_nl = true; | |
657 | 657 | |||
658 | if (code.len > 0 && !ps.in_init) { | 658 | if (code.len > 0 && !ps.in_init) { | |
659 | if (!opt.brace_same_line || | 659 | if (!opt.brace_same_line || | |
660 | (code.len > 0 && code.s[code.len - 1] == '}')) | 660 | (code.len > 0 && code.s[code.len - 1] == '}')) | |
661 | output_line(); | 661 | output_line(); | |
662 | else if (ps.in_func_def_params && !ps.in_var_decl) { | 662 | else if (ps.in_func_def_params && !ps.in_var_decl) { | |
663 | ps.ind_level_follow = 0; | 663 | ps.ind_level_follow = 0; | |
664 | if (opt.function_brace_split) | 664 | if (opt.function_brace_split) | |
665 | output_line(); | 665 | output_line(); | |
666 | else | 666 | else | |
667 | ps.want_blank = true; | 667 | ps.want_blank = true; | |
668 | } | 668 | } | |
669 | } | 669 | } | |
670 | 670 | |||
671 | if (ps.nparen > 0 && ps.init_level == 0) { | 671 | if (ps.nparen > 0 && ps.init_level == 0) { | |
672 | diag(1, "Unbalanced parentheses"); | 672 | diag(1, "Unbalanced parentheses"); | |
673 | ps.nparen = 0; | 673 | ps.nparen = 0; | |
674 | if (ps.spaced_expr_psym != psym_0) { | 674 | if (ps.spaced_expr_psym != psym_0) { | |
675 | parse(ps.spaced_expr_psym); | 675 | parse(ps.spaced_expr_psym); | |
676 | ps.spaced_expr_psym = psym_0; | 676 | ps.spaced_expr_psym = psym_0; | |
677 | ps.ind_level = ps.ind_level_follow; | 677 | ps.ind_level = ps.ind_level_follow; | |
678 | } | 678 | } | |
679 | } | 679 | } | |
680 | 680 | |||
681 | if (code.len == 0) | 681 | if (code.len == 0) | |
682 | ps.in_stmt_cont = false; /* don't indent the '{' itself | 682 | ps.in_stmt_cont = false; /* don't indent the '{' itself | |
683 | */ | 683 | */ | |
684 | if (ps.in_decl && ps.in_var_decl) { | 684 | if (ps.in_decl && ps.in_var_decl) { | |
685 | ps.di_stack[ps.decl_level] = ps.decl_ind; | 685 | ps.di_stack[ps.decl_level] = ps.decl_ind; | |
686 | if (++ps.decl_level == (int)array_length(ps.di_stack)) { | 686 | if (++ps.decl_level == (int)array_length(ps.di_stack)) { | |
687 | diag(0, "Reached internal limit of %zu struct levels", | 687 | diag(0, "Reached internal limit of %zu struct levels", | |
688 | array_length(ps.di_stack)); | 688 | array_length(ps.di_stack)); | |
689 | ps.decl_level--; | 689 | ps.decl_level--; | |
690 | } | 690 | } | |
691 | } else { | 691 | } else { | |
692 | ps.line_has_decl = false; /* we can't be in the middle of | 692 | ps.line_has_decl = false; /* we can't be in the middle of | |
693 | * a declaration, so don't do | 693 | * a declaration, so don't do | |
694 | * special indentation of | 694 | * special indentation of | |
695 | * comments */ | 695 | * comments */ | |
696 | ps.in_func_def_params = false; | 696 | ps.in_func_def_params = false; | |
697 | ps.in_decl = false; | 697 | ps.in_decl = false; | |
698 | } | 698 | } | |
699 | 699 | |||
700 | ps.decl_ind = 0; | 700 | ps.decl_ind = 0; | |
701 | parse(ps.lbrace_kind); | 701 | parse(ps.lbrace_kind); | |
702 | if (ps.want_blank) | 702 | if (ps.want_blank) | |
703 | buf_add_char(&code, ' '); | 703 | buf_add_char(&code, ' '); | |
704 | ps.want_blank = false; | 704 | ps.want_blank = false; | |
705 | buf_add_char(&code, '{'); | 705 | buf_add_char(&code, '{'); | |
706 | ps.declaration = decl_no; | 706 | ps.declaration = decl_no; | |
707 | } | 707 | } | |
708 | 708 | |||
709 | static void | 709 | static void | |
710 | process_rbrace(void) | 710 | process_rbrace(void) | |
711 | { | 711 | { | |
712 | if (ps.nparen > 0 && ps.init_level == 0) { | 712 | if (ps.nparen > 0 && ps.init_level == 0) { | |
713 | diag(1, "Unbalanced parentheses"); | 713 | diag(1, "Unbalanced parentheses"); | |
714 | ps.nparen = 0; | 714 | ps.nparen = 0; | |
715 | ps.spaced_expr_psym = psym_0; | 715 | ps.spaced_expr_psym = psym_0; | |
716 | } | 716 | } | |
717 | 717 | |||
718 | ps.declaration = decl_no; | 718 | ps.declaration = decl_no; | |
719 | if (ps.init_level > 0) | 719 | if (ps.init_level > 0) | |
720 | ps.init_level--; | 720 | ps.init_level--; | |
721 | 721 | |||
722 | if (code.len > 0 && !ps.in_init) | 722 | if (code.len > 0 && !ps.in_init) | |
723 | output_line(); | 723 | output_line(); | |
724 | 724 | |||
725 | buf_add_char(&code, '}'); | 725 | buf_add_char(&code, '}'); | |
726 | ps.want_blank = true; | 726 | ps.want_blank = true; | |
727 | ps.in_stmt_or_decl = false; // XXX: Initializers don't end a stmt | 727 | ps.in_stmt_or_decl = false; // XXX: Initializers don't end a stmt | |
728 | ps.in_stmt_cont = false; | 728 | ps.in_stmt_cont = false; | |
729 | 729 | |||
730 | if (ps.decl_level > 0) { /* multi-level structure declaration */ | 730 | if (ps.decl_level > 0) { /* multi-level structure declaration */ | |
731 | ps.decl_ind = ps.di_stack[--ps.decl_level]; | 731 | ps.decl_ind = ps.di_stack[--ps.decl_level]; | |
732 | if (ps.decl_level == 0 && !ps.in_func_def_params) { | 732 | if (ps.decl_level == 0 && !ps.in_func_def_params) { | |
733 | ps.declaration = decl_begin; | 733 | ps.declaration = decl_begin; | |
734 | ps.decl_ind = ps.ind_level == 0 | 734 | ps.decl_ind = ps.ind_level == 0 | |
735 | ? opt.decl_indent : opt.local_decl_indent; | 735 | ? opt.decl_indent : opt.local_decl_indent; | |
736 | } | 736 | } | |
737 | ps.in_decl = true; | 737 | ps.in_decl = true; | |
738 | } | 738 | } | |
739 | 739 | |||
740 | if (ps.psyms.top == 2) | 740 | if (ps.psyms.top == 2) | |
741 | out.line_kind = lk_func_end; | 741 | out.line_kind = lk_func_end; | |
742 | 742 | |||
743 | parse(psym_rbrace); | 743 | parse(psym_rbrace); | |
744 | 744 | |||
745 | if (!ps.in_var_decl | 745 | if (!ps.in_var_decl | |
746 | && ps.psyms.sym[ps.psyms.top] != psym_do_stmt | 746 | && ps.psyms.sym[ps.psyms.top] != psym_do_stmt | |
747 | && ps.psyms.sym[ps.psyms.top] != psym_if_expr_stmt) | 747 | && ps.psyms.sym[ps.psyms.top] != psym_if_expr_stmt) | |
748 | ps.force_nl = true; | 748 | ps.force_nl = true; | |
749 | } | 749 | } | |
750 | 750 | |||
751 | static void | 751 | static void | |
752 | process_period(void) | 752 | process_period(void) | |
753 | { | 753 | { | |
754 | if (code.len > 0 && code.s[code.len - 1] == ',') | 754 | if (code.len > 0 && code.s[code.len - 1] == ',') | |
755 | buf_add_char(&code, ' '); | 755 | buf_add_char(&code, ' '); | |
756 | buf_add_char(&code, '.'); | 756 | buf_add_char(&code, '.'); | |
757 | ps.want_blank = false; | 757 | ps.want_blank = false; | |
758 | } | 758 | } | |
759 | 759 | |||
760 | static void | 760 | static void | |
761 | process_unary_op(void) | 761 | process_unary_op(void) | |
762 | { | 762 | { | |
763 | if (is_function_pointer_declaration()) { | 763 | if (is_function_pointer_declaration()) { | |
764 | int ind = ps.decl_ind - (int)token.len; | 764 | int ind = ps.decl_ind - (int)token.len; | |
765 | indent_declarator(ind, ps.tabs_to_var); | 765 | indent_declarator(ind, ps.tabs_to_var); | |
766 | ps.want_blank = false; | 766 | ps.want_blank = false; | |
767 | } else if ((token.s[0] == '+' || token.s[0] == '-') | 767 | } else if ((token.s[0] == '+' || token.s[0] == '-') | |
768 | && code.len > 0 && code.s[code.len - 1] == token.s[0]) | 768 | && code.len > 0 && code.s[code.len - 1] == token.s[0]) | |
769 | ps.want_blank = true; | 769 | ps.want_blank = true; | |
770 | 770 | |||
771 | if (ps.want_blank) | 771 | if (ps.want_blank) | |
772 | buf_add_char(&code, ' '); | 772 | buf_add_char(&code, ' '); | |
773 | buf_add_buf(&code, &token); | 773 | buf_add_buf(&code, &token); | |
774 | ps.want_blank = false; | 774 | ps.want_blank = false; | |
775 | } | 775 | } | |
776 | 776 | |||
777 | static void | 777 | static void | |
778 | process_postfix_op(void) | 778 | process_postfix_op(void) | |
779 | { | 779 | { | |
780 | buf_add_buf(&code, &token); | 780 | buf_add_buf(&code, &token); | |
781 | ps.want_blank = true; | 781 | ps.want_blank = true; | |
782 | } | 782 | } | |
783 | 783 | |||
784 | static void | 784 | static void | |
785 | process_comma(void) | 785 | process_comma(void) | |
786 | { | 786 | { | |
787 | ps.want_blank = code.len > 0; /* only put blank after comma if comma | 787 | ps.want_blank = code.len > 0; /* only put blank after comma if comma | |
788 | * does not start the line */ | 788 | * does not start the line */ | |
789 | 789 | |||
790 | if (ps.in_decl && !ps.line_has_func_def && !ps.in_init && | 790 | if (ps.in_decl && !ps.line_has_func_def && !ps.in_init && | |
791 | !ps.decl_indent_done && ps.line_start_nparen == 0) { | 791 | !ps.decl_indent_done && ps.ind_paren_level == 0) { | |
792 | /* indent leading commas and not the actual identifiers */ | 792 | /* indent leading commas and not the actual identifiers */ | |
793 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | 793 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | |
794 | } | 794 | } | |
795 | 795 | |||
796 | buf_add_char(&code, ','); | 796 | buf_add_char(&code, ','); | |
797 | 797 | |||
798 | if (ps.nparen == 0) { | 798 | if (ps.nparen == 0) { | |
799 | if (ps.init_level == 0) | 799 | if (ps.init_level == 0) | |
800 | ps.in_init = false; | 800 | ps.in_init = false; | |
801 | int typical_varname_length = 8; | 801 | int typical_varname_length = 8; | |
802 | if (ps.break_after_comma && (opt.break_after_comma || | 802 | if (ps.break_after_comma && (opt.break_after_comma || | |
803 | ind_add(compute_code_indent(), code.s, code.len) | 803 | ind_add(compute_code_indent(), code.s, code.len) | |
804 | >= opt.max_line_length - typical_varname_length)) | 804 | >= opt.max_line_length - typical_varname_length)) | |
805 | ps.force_nl = true; | 805 | ps.force_nl = true; | |
806 | } | 806 | } | |
807 | } | 807 | } | |
808 | 808 | |||
809 | static void | 809 | static void | |
810 | process_label_colon(void) | 810 | process_label_colon(void) | |
811 | { | 811 | { | |
812 | buf_add_buf(&lab, &code); | 812 | buf_add_buf(&lab, &code); | |
813 | buf_add_char(&lab, ':'); | 813 | buf_add_char(&lab, ':'); | |
814 | buf_clear(&code); | 814 | buf_clear(&code); | |
815 | 815 | |||
816 | if (ps.seen_case) | 816 | if (ps.seen_case) | |
817 | out.line_kind = lk_case_or_default; | 817 | out.line_kind = lk_case_or_default; | |
818 | ps.in_stmt_or_decl = false; | 818 | ps.in_stmt_or_decl = false; | |
819 | ps.force_nl = ps.seen_case; | 819 | ps.force_nl = ps.seen_case; | |
820 | ps.seen_case = false; | 820 | ps.seen_case = false; | |
821 | ps.want_blank = false; | 821 | ps.want_blank = false; | |
822 | } | 822 | } | |
823 | 823 | |||
824 | static void | 824 | static void | |
825 | process_other_colon(void) | 825 | process_other_colon(void) | |
826 | { | 826 | { | |
827 | buf_add_char(&code, ':'); | 827 | buf_add_char(&code, ':'); | |
828 | ps.want_blank = ps.decl_level == 0; | 828 | ps.want_blank = ps.decl_level == 0; | |
829 | } | 829 | } | |
830 | 830 | |||
831 | static void | 831 | static void | |
832 | process_semicolon(void) | 832 | process_semicolon(void) | |
833 | { | 833 | { | |
834 | if (out.line_kind == lk_stmt_head) | 834 | if (out.line_kind == lk_stmt_head) | |
835 | out.line_kind = lk_other; | 835 | out.line_kind = lk_other; | |
836 | if (ps.decl_level == 0) | 836 | if (ps.decl_level == 0) | |
837 | ps.in_var_decl = false; | 837 | ps.in_var_decl = false; | |
838 | ps.seen_case = false; /* only needs to be reset on error */ | 838 | ps.seen_case = false; /* only needs to be reset on error */ | |
839 | ps.quest_level = 0; /* only needs to be reset on error */ | 839 | ps.quest_level = 0; /* only needs to be reset on error */ | |
840 | if (ps.prev_lsym == lsym_rparen) | 840 | if (ps.prev_lsym == lsym_rparen) | |
841 | ps.in_func_def_params = false; | 841 | ps.in_func_def_params = false; | |
842 | ps.in_init = false; | 842 | ps.in_init = false; | |
843 | ps.init_level = 0; | 843 | ps.init_level = 0; | |
844 | ps.declaration = ps.declaration == decl_begin ? decl_end : decl_no; | 844 | ps.declaration = ps.declaration == decl_begin ? decl_end : decl_no; | |
845 | 845 | |||
846 | if (ps.in_decl && code.len == 0 && !ps.in_init && | 846 | if (ps.in_decl && code.len == 0 && !ps.in_init && | |
847 | !ps.decl_indent_done && ps.line_start_nparen == 0) { | 847 | !ps.decl_indent_done && ps.ind_paren_level == 0) { | |
848 | /* indent stray semicolons in declarations */ | 848 | /* indent stray semicolons in declarations */ | |
849 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | 849 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | |
850 | } | 850 | } | |
851 | 851 | |||
852 | ps.in_decl = ps.decl_level > 0; /* if we were in a first level | 852 | ps.in_decl = ps.decl_level > 0; /* if we were in a first level | |
853 | * structure declaration before, we | 853 | * structure declaration before, we | |
854 | * aren't anymore */ | 854 | * aren't anymore */ | |
855 | 855 | |||
856 | if (ps.nparen > 0 && ps.spaced_expr_psym != psym_for_exprs) { | 856 | if (ps.nparen > 0 && ps.spaced_expr_psym != psym_for_exprs) { | |
857 | /* There were unbalanced parentheses in the statement. It is a | 857 | /* There were unbalanced parentheses in the statement. It is a | |
858 | * bit complicated, because the semicolon might be in a for | 858 | * bit complicated, because the semicolon might be in a for | |
859 | * statement. */ | 859 | * statement. */ | |
860 | diag(1, "Unbalanced parentheses"); | 860 | diag(1, "Unbalanced parentheses"); | |
861 | ps.nparen = 0; | 861 | ps.nparen = 0; | |
862 | if (ps.spaced_expr_psym != psym_0) { | 862 | if (ps.spaced_expr_psym != psym_0) { | |
863 | parse(ps.spaced_expr_psym); | 863 | parse(ps.spaced_expr_psym); | |
864 | ps.spaced_expr_psym = psym_0; | 864 | ps.spaced_expr_psym = psym_0; | |
865 | } | 865 | } | |
866 | } | 866 | } | |
867 | buf_add_char(&code, ';'); | 867 | buf_add_char(&code, ';'); | |
868 | ps.want_blank = true; | 868 | ps.want_blank = true; | |
869 | ps.in_stmt_or_decl = ps.nparen > 0; | 869 | ps.in_stmt_or_decl = ps.nparen > 0; | |
870 | ps.decl_ind = 0; | 870 | ps.decl_ind = 0; | |
871 | 871 | |||
872 | if (ps.spaced_expr_psym == psym_0) { | 872 | if (ps.spaced_expr_psym == psym_0) { | |
873 | parse(psym_stmt); | 873 | parse(psym_stmt); | |
874 | ps.force_nl = true; | 874 | ps.force_nl = true; | |
875 | } | 875 | } | |
876 | } | 876 | } | |
877 | 877 | |||
878 | static void | 878 | static void | |
879 | process_type_outside_parentheses(void) | 879 | process_type_outside_parentheses(void) | |
880 | { | 880 | { | |
881 | parse(psym_decl); /* let the parser worry about indentation */ | 881 | parse(psym_decl); /* let the parser worry about indentation */ | |
882 | 882 | |||
883 | if (ps.prev_lsym == lsym_rparen && ps.psyms.top <= 1 && code.len > 0) | 883 | if (ps.prev_lsym == lsym_rparen && ps.psyms.top <= 1 && code.len > 0) | |
884 | output_line(); | 884 | output_line(); | |
885 | 885 | |||
886 | if (ps.in_func_def_params && opt.indent_parameters && | 886 | if (ps.in_func_def_params && opt.indent_parameters && | |
887 | ps.decl_level == 0) { | 887 | ps.decl_level == 0) { | |
888 | ps.ind_level = ps.ind_level_follow = 1; | 888 | ps.ind_level = ps.ind_level_follow = 1; | |
889 | ps.in_stmt_cont = false; | 889 | ps.in_stmt_cont = false; | |
890 | } | 890 | } | |
891 | 891 | |||
892 | ps.in_var_decl = /* maybe */ true; | 892 | ps.in_var_decl = /* maybe */ true; | |
893 | ps.in_decl = ps.line_has_decl = ps.prev_lsym != lsym_typedef; | 893 | ps.in_decl = ps.line_has_decl = ps.prev_lsym != lsym_typedef; | |
894 | if (ps.decl_level <= 0) | 894 | if (ps.decl_level <= 0) | |
895 | ps.declaration = decl_begin; | 895 | ps.declaration = decl_begin; | |
896 | 896 | |||
897 | int len = (int)token.len + 1; | 897 | int len = (int)token.len + 1; | |
898 | int ind = ps.ind_level > 0 && ps.decl_level == 0 | 898 | int ind = ps.ind_level > 0 && ps.decl_level == 0 | |
899 | ? opt.local_decl_indent /* local variable */ | 899 | ? opt.local_decl_indent /* local variable */ | |
900 | : opt.decl_indent; /* global variable, or member */ | 900 | : opt.decl_indent; /* global variable, or member */ | |
901 | ps.decl_ind = ind > 0 ? ind : len; | 901 | ps.decl_ind = ind > 0 ? ind : len; | |
902 | ps.tabs_to_var = opt.use_tabs && ind > 0; | 902 | ps.tabs_to_var = opt.use_tabs && ind > 0; | |
903 | } | 903 | } | |
904 | 904 | |||
905 | static void | 905 | static void | |
906 | process_word(lexer_symbol lsym) | 906 | process_word(lexer_symbol lsym) | |
907 | { | 907 | { | |
908 | if (ps.in_decl) { | 908 | if (ps.in_decl) { | |
909 | if (lsym == lsym_funcname) { | 909 | if (lsym == lsym_funcname) { | |
910 | ps.in_decl = false; | 910 | ps.in_decl = false; | |
911 | if (opt.procnames_start_line && code.len > 0) | 911 | if (opt.procnames_start_line && code.len > 0) | |
912 | output_line(); | 912 | output_line(); | |
913 | else if (ps.want_blank) | 913 | else if (ps.want_blank) | |
914 | buf_add_char(&code, ' '); | 914 | buf_add_char(&code, ' '); | |
915 | ps.want_blank = false; | 915 | ps.want_blank = false; | |
916 | 916 | |||
917 | } else if (!ps.in_init && !ps.decl_indent_done && | 917 | } else if (!ps.in_init && !ps.decl_indent_done && | |
918 | ps.line_start_nparen == 0) { | 918 | ps.ind_paren_level == 0) { | |
919 | if (opt.decl_indent == 0 | 919 | if (opt.decl_indent == 0 | |
920 | && code.len > 0 && code.s[code.len - 1] == '}') | 920 | && code.len > 0 && code.s[code.len - 1] == '}') | |
921 | ps.decl_ind = ind_add(0, code.s, code.len) + 1; | 921 | ps.decl_ind = ind_add(0, code.s, code.len) + 1; | |
922 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | 922 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | |
923 | ps.want_blank = false; | 923 | ps.want_blank = false; | |
924 | } | 924 | } | |
925 | 925 | |||
926 | } else if (ps.spaced_expr_psym != psym_0 && ps.nparen == 0) { | 926 | } else if (ps.spaced_expr_psym != psym_0 && ps.nparen == 0) { | |
927 | ps.force_nl = true; | 927 | ps.force_nl = true; | |
928 | ps.in_stmt_or_decl = false; | 928 | ps.in_stmt_or_decl = false; | |
929 | ps.next_unary = true; | 929 | ps.next_unary = true; | |
930 | parse(ps.spaced_expr_psym); | 930 | parse(ps.spaced_expr_psym); | |
931 | ps.spaced_expr_psym = psym_0; | 931 | ps.spaced_expr_psym = psym_0; | |
932 | } | 932 | } | |
933 | } | 933 | } | |
934 | 934 | |||
935 | static void | 935 | static void | |
936 | process_do(void) | 936 | process_do(void) | |
937 | { | 937 | { | |
938 | ps.in_stmt_or_decl = false; | 938 | ps.in_stmt_or_decl = false; | |
939 | ps.in_decl = false; | 939 | ps.in_decl = false; | |
940 | 940 | |||
941 | if (code.len > 0) | 941 | if (code.len > 0) | |
942 | output_line(); | 942 | output_line(); | |
943 | 943 | |||
944 | ps.force_nl = true; | 944 | ps.force_nl = true; | |
945 | parse(psym_do); | 945 | parse(psym_do); | |
946 | } | 946 | } | |
947 | 947 | |||
948 | static void | 948 | static void | |
949 | process_else(void) | 949 | process_else(void) | |
950 | { | 950 | { | |
951 | ps.in_stmt_or_decl = false; | 951 | ps.in_stmt_or_decl = false; | |
952 | 952 | |||
953 | if (code.len > 0 | 953 | if (code.len > 0 | |
954 | && !(opt.cuddle_else && code.s[code.len - 1] == '}')) | 954 | && !(opt.cuddle_else && code.s[code.len - 1] == '}')) | |
955 | output_line(); | 955 | output_line(); | |
956 | 956 | |||
957 | ps.force_nl = true; | 957 | ps.force_nl = true; | |
958 | parse(psym_else); | 958 | parse(psym_else); | |
959 | } | 959 | } | |
960 | 960 | |||
961 | static void | 961 | static void | |
962 | process_lsym(lexer_symbol lsym) | 962 | process_lsym(lexer_symbol lsym) | |
963 | { | 963 | { | |
964 | switch (lsym) { | 964 | switch (lsym) { | |
965 | /* INDENT OFF */ | 965 | /* INDENT OFF */ | |
966 | case lsym_preprocessing: process_preprocessing(); break; | 966 | case lsym_preprocessing: process_preprocessing(); break; | |
967 | case lsym_newline: process_newline(); break; | 967 | case lsym_newline: process_newline(); break; | |
968 | case lsym_comment: process_comment(); break; | 968 | case lsym_comment: process_comment(); break; | |
969 | case lsym_lparen: process_lparen(); break; | 969 | case lsym_lparen: process_lparen(); break; | |
970 | case lsym_lbracket: process_lbracket(); break; | 970 | case lsym_lbracket: process_lbracket(); break; | |
971 | case lsym_rparen: process_rparen(); break; | 971 | case lsym_rparen: process_rparen(); break; | |
972 | case lsym_rbracket: process_rbracket(); break; | 972 | case lsym_rbracket: process_rbracket(); break; | |
973 | case lsym_lbrace: process_lbrace(); break; | 973 | case lsym_lbrace: process_lbrace(); break; | |
974 | case lsym_rbrace: process_rbrace(); break; | 974 | case lsym_rbrace: process_rbrace(); break; | |
975 | case lsym_period: process_period(); break; | 975 | case lsym_period: process_period(); break; | |
976 | case lsym_unary_op: process_unary_op(); break; | 976 | case lsym_unary_op: process_unary_op(); break; | |
977 | case lsym_postfix_op: process_postfix_op(); break; | 977 | case lsym_postfix_op: process_postfix_op(); break; | |
978 | case lsym_binary_op: goto copy_token; | 978 | case lsym_binary_op: goto copy_token; | |
979 | case lsym_question: ps.quest_level++; goto copy_token; | 979 | case lsym_question: ps.quest_level++; goto copy_token; | |
980 | case lsym_question_colon: goto copy_token; | 980 | case lsym_question_colon: goto copy_token; | |
981 | case lsym_label_colon: process_label_colon(); break; | 981 | case lsym_label_colon: process_label_colon(); break; | |
982 | case lsym_other_colon: process_other_colon(); break; | 982 | case lsym_other_colon: process_other_colon(); break; | |
983 | case lsym_comma: process_comma(); break; | 983 | case lsym_comma: process_comma(); break; | |
984 | case lsym_semicolon: process_semicolon(); break; | 984 | case lsym_semicolon: process_semicolon(); break; | |
985 | case lsym_typedef: goto copy_token; | 985 | case lsym_typedef: goto copy_token; | |
986 | case lsym_modifier: goto copy_token; | 986 | case lsym_modifier: goto copy_token; | |
987 | case lsym_case: ps.seen_case = true; goto copy_token; | 987 | case lsym_case: ps.seen_case = true; goto copy_token; | |
988 | case lsym_default: ps.seen_case = true; goto copy_token; | 988 | case lsym_default: ps.seen_case = true; goto copy_token; | |
989 | case lsym_do: process_do(); goto copy_token; | 989 | case lsym_do: process_do(); goto copy_token; | |
990 | case lsym_else: process_else(); goto copy_token; | 990 | case lsym_else: process_else(); goto copy_token; | |
991 | case lsym_for: ps.spaced_expr_psym = psym_for_exprs; goto copy_token; | 991 | case lsym_for: ps.spaced_expr_psym = psym_for_exprs; goto copy_token; | |
992 | case lsym_if: ps.spaced_expr_psym = psym_if_expr; goto copy_token; | 992 | case lsym_if: ps.spaced_expr_psym = psym_if_expr; goto copy_token; | |
993 | case lsym_switch: ps.spaced_expr_psym = psym_switch_expr; goto copy_token; | 993 | case lsym_switch: ps.spaced_expr_psym = psym_switch_expr; goto copy_token; | |
994 | case lsym_while: ps.spaced_expr_psym = psym_while_expr; goto copy_token; | 994 | case lsym_while: ps.spaced_expr_psym = psym_while_expr; goto copy_token; | |
995 | /* INDENT ON */ | 995 | /* INDENT ON */ | |
996 | 996 | |||
997 | case lsym_tag: | 997 | case lsym_tag: | |
998 | if (ps.nparen > 0) | 998 | if (ps.nparen > 0) | |
999 | goto copy_token; | 999 | goto copy_token; | |
1000 | /* FALLTHROUGH */ | 1000 | /* FALLTHROUGH */ | |
1001 | case lsym_type_outside_parentheses: | 1001 | case lsym_type_outside_parentheses: | |
1002 | process_type_outside_parentheses(); | 1002 | process_type_outside_parentheses(); | |
1003 | goto copy_token; | 1003 | goto copy_token; | |
1004 | 1004 | |||
1005 | case lsym_type_in_parentheses: | 1005 | case lsym_type_in_parentheses: | |
1006 | case lsym_sizeof: | 1006 | case lsym_sizeof: | |
1007 | case lsym_offsetof: | 1007 | case lsym_offsetof: | |
1008 | case lsym_word: | 1008 | case lsym_word: | |
1009 | case lsym_funcname: | 1009 | case lsym_funcname: | |
1010 | case lsym_return: | 1010 | case lsym_return: | |
1011 | process_word(lsym); | 1011 | process_word(lsym); | |
1012 | copy_token: | 1012 | copy_token: | |
1013 | if (ps.want_blank) | 1013 | if (ps.want_blank) | |
1014 | buf_add_char(&code, ' '); | 1014 | buf_add_char(&code, ' '); | |
1015 | buf_add_buf(&code, &token); | 1015 | buf_add_buf(&code, &token); | |
1016 | if (lsym != lsym_funcname) | 1016 | if (lsym != lsym_funcname) | |
1017 | ps.want_blank = true; | 1017 | ps.want_blank = true; | |
1018 | break; | 1018 | break; | |
1019 | 1019 | |||
1020 | default: | 1020 | default: | |
1021 | break; | 1021 | break; | |
1022 | } | 1022 | } | |
1023 | } | 1023 | } | |
1024 | 1024 | |||
1025 | static int | 1025 | static int | |
1026 | indent(void) | 1026 | indent(void) | |
1027 | { | 1027 | { | |
1028 | debug_parser_state(); | 1028 | debug_parser_state(); | |
1029 | 1029 | |||
1030 | for (;;) { /* loop until we reach eof */ | 1030 | for (;;) { /* loop until we reach eof */ | |
1031 | lexer_symbol lsym = lexi(); | 1031 | lexer_symbol lsym = lexi(); | |
1032 | 1032 | |||
1033 | debug_blank_line(); | 1033 | debug_blank_line(); | |
1034 | debug_printf("line %d: %s", line_no, lsym_name[lsym]); | 1034 | debug_printf("line %d: %s", line_no, lsym_name[lsym]); | |
1035 | debug_print_buf("token", &token); | 1035 | debug_print_buf("token", &token); | |
1036 | debug_buffers(); | 1036 | debug_buffers(); | |
1037 | debug_blank_line(); | 1037 | debug_blank_line(); | |
1038 | 1038 | |||
1039 | if (lsym == lsym_eof) | 1039 | if (lsym == lsym_eof) | |
1040 | return process_eof(); | 1040 | return process_eof(); | |
1041 | 1041 | |||
1042 | if (lsym == lsym_if && ps.prev_lsym == lsym_else | 1042 | if (lsym == lsym_if && ps.prev_lsym == lsym_else | |
1043 | && opt.else_if_in_same_line) | 1043 | && opt.else_if_in_same_line) | |
1044 | ps.force_nl = false; | 1044 | ps.force_nl = false; | |
1045 | 1045 | |||
1046 | if (lsym == lsym_preprocessing || lsym == lsym_newline) | 1046 | if (lsym == lsym_preprocessing || lsym == lsym_newline) | |
1047 | ps.force_nl = false; | 1047 | ps.force_nl = false; | |
1048 | else if (lsym == lsym_comment) { | 1048 | else if (lsym == lsym_comment) { | |
1049 | /* no special processing */ | 1049 | /* no special processing */ | |
1050 | } else { | 1050 | } else { | |
1051 | if (ps.force_nl && should_break_line(lsym)) { | 1051 | if (ps.force_nl && should_break_line(lsym)) { | |
1052 | ps.force_nl = false; | 1052 | ps.force_nl = false; | |
1053 | output_line(); | 1053 | output_line(); | |
1054 | } | 1054 | } | |
1055 | ps.in_stmt_or_decl = true; | 1055 | ps.in_stmt_or_decl = true; | |
1056 | if (com.len > 0) | 1056 | if (com.len > 0) | |
1057 | move_com_to_code(lsym); | 1057 | move_com_to_code(lsym); | |
1058 | update_ps_lbrace_kind(lsym); | 1058 | update_ps_lbrace_kind(lsym); | |
1059 | } | 1059 | } | |
1060 | 1060 | |||
1061 | process_lsym(lsym); | 1061 | process_lsym(lsym); | |
1062 | 1062 | |||
1063 | if (lsym != lsym_preprocessing | 1063 | if (lsym != lsym_preprocessing | |
1064 | && lsym != lsym_newline | 1064 | && lsym != lsym_newline | |
1065 | && lsym != lsym_comment) | 1065 | && lsym != lsym_comment) | |
1066 | ps.prev_lsym = lsym; | 1066 | ps.prev_lsym = lsym; | |
1067 | 1067 | |||
1068 | debug_parser_state(); | 1068 | debug_parser_state(); | |
1069 | } | 1069 | } | |
1070 | } | 1070 | } | |
1071 | 1071 | |||
1072 | int | 1072 | int | |
1073 | main(int argc, char **argv) | 1073 | main(int argc, char **argv) | |
1074 | { | 1074 | { | |
1075 | init_globals(); | 1075 | init_globals(); | |
1076 | load_profiles(argc, argv); | 1076 | load_profiles(argc, argv); | |
1077 | parse_command_line(argc, argv); | 1077 | parse_command_line(argc, argv); | |
1078 | set_initial_indentation(); | 1078 | set_initial_indentation(); | |
1079 | return indent(); | 1079 | return indent(); | |
1080 | } | 1080 | } |
--- src/usr.bin/indent/indent.h 2023/06/10 16:43:56 1.187
+++ src/usr.bin/indent/indent.h 2023/06/10 21:36:38 1.188
@@ -1,536 +1,535 @@ | @@ -1,536 +1,535 @@ | |||
1 | /* $NetBSD: indent.h,v 1.187 2023/06/10 16:43:56 rillig Exp $ */ | 1 | /* $NetBSD: indent.h,v 1.188 2023/06/10 21:36:38 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 | |
15 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. | |
17 | * | 17 | * | |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND | |
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE | 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE | |
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
28 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. | |
29 | */ | 29 | */ | |
30 | /*- | 30 | /*- | |
31 | * SPDX-License-Identifier: BSD-4-Clause | 31 | * SPDX-License-Identifier: BSD-4-Clause | |
32 | * | 32 | * | |
33 | * Copyright (c) 1985 Sun Microsystems, Inc. | 33 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
34 | * Copyright (c) 1980, 1993 | 34 | * Copyright (c) 1980, 1993 | |
35 | * The Regents of the University of California. All rights reserved. | 35 | * The Regents of the University of California. All rights reserved. | |
36 | * All rights reserved. | 36 | * All rights reserved. | |
37 | * | 37 | * | |
38 | * Redistribution and use in source and binary forms, with or without | 38 | * Redistribution and use in source and binary forms, with or without | |
39 | * modification, are permitted provided that the following conditions | 39 | * modification, are permitted provided that the following conditions | |
40 | * are met: | 40 | * are met: | |
41 | * 1. Redistributions of source code must retain the above copyright | 41 | * 1. Redistributions of source code must retain the above copyright | |
42 | * notice, this list of conditions and the following disclaimer. | 42 | * notice, this list of conditions and the following disclaimer. | |
43 | * 2. Redistributions in binary form must reproduce the above copyright | 43 | * 2. Redistributions in binary form must reproduce the above copyright | |
44 | * notice, this list of conditions and the following disclaimer in the | 44 | * notice, this list of conditions and the following disclaimer in the | |
45 | * documentation and/or other materials provided with the distribution. | 45 | * documentation and/or other materials provided with the distribution. | |
46 | * 3. All advertising materials mentioning features or use of this software | 46 | * 3. All advertising materials mentioning features or use of this software | |
47 | * must display the following acknowledgement: | 47 | * must display the following acknowledgement: | |
48 | * This product includes software developed by the University of | 48 | * This product includes software developed by the University of | |
49 | * California, Berkeley and its contributors. | 49 | * California, Berkeley and its contributors. | |
50 | * 4. Neither the name of the University nor the names of its contributors | 50 | * 4. Neither the name of the University nor the names of its contributors | |
51 | * may be used to endorse or promote products derived from this software | 51 | * may be used to endorse or promote products derived from this software | |
52 | * without specific prior written permission. | 52 | * without specific prior written permission. | |
53 | * | 53 | * | |
54 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 54 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
55 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 55 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 56 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 57 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 58 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 59 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 60 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 61 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 62 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 63 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
64 | * SUCH DAMAGE. | 64 | * SUCH DAMAGE. | |
65 | */ | 65 | */ | |
66 | 66 | |||
67 | #include <ctype.h> | 67 | #include <ctype.h> | |
68 | #include <stdbool.h> | 68 | #include <stdbool.h> | |
69 | #include <stdio.h> | 69 | #include <stdio.h> | |
70 | 70 | |||
71 | typedef enum lexer_symbol { | 71 | typedef enum lexer_symbol { | |
72 | lsym_eof, | 72 | lsym_eof, | |
73 | lsym_preprocessing, /* the initial '#' of a preprocessing line */ | 73 | lsym_preprocessing, /* the initial '#' of a preprocessing line */ | |
74 | lsym_newline, | 74 | lsym_newline, | |
75 | lsym_comment, /* the initial '/ *' or '//' of a comment */ | 75 | lsym_comment, /* the initial '/ *' or '//' of a comment */ | |
76 | 76 | |||
77 | lsym_lparen, | 77 | lsym_lparen, | |
78 | lsym_rparen, | 78 | lsym_rparen, | |
79 | lsym_lbracket, | 79 | lsym_lbracket, | |
80 | lsym_rbracket, | 80 | lsym_rbracket, | |
81 | lsym_lbrace, | 81 | lsym_lbrace, | |
82 | lsym_rbrace, | 82 | lsym_rbrace, | |
83 | 83 | |||
84 | lsym_period, | 84 | lsym_period, | |
85 | lsym_unary_op, /* e.g. '*', '&', '-' or leading '++' */ | 85 | lsym_unary_op, /* e.g. '*', '&', '-' or leading '++' */ | |
86 | lsym_sizeof, | 86 | lsym_sizeof, | |
87 | lsym_offsetof, | 87 | lsym_offsetof, | |
88 | lsym_postfix_op, /* trailing '++' or '--' */ | 88 | lsym_postfix_op, /* trailing '++' or '--' */ | |
89 | lsym_binary_op, /* e.g. '*', '&', '<<', '&&' or '/=' */ | 89 | lsym_binary_op, /* e.g. '*', '&', '<<', '&&' or '/=' */ | |
90 | lsym_question, /* the '?' from a '?:' expression */ | 90 | lsym_question, /* the '?' from a '?:' expression */ | |
91 | lsym_question_colon, /* the ':' from a '?:' expression */ | 91 | lsym_question_colon, /* the ':' from a '?:' expression */ | |
92 | lsym_comma, | 92 | lsym_comma, | |
93 | 93 | |||
94 | lsym_typedef, | 94 | lsym_typedef, | |
95 | lsym_modifier, /* modifiers for types, functions, variables */ | 95 | lsym_modifier, /* modifiers for types, functions, variables */ | |
96 | lsym_tag, /* 'struct', 'union' or 'enum' */ | 96 | lsym_tag, /* 'struct', 'union' or 'enum' */ | |
97 | lsym_type_outside_parentheses, | 97 | lsym_type_outside_parentheses, | |
98 | lsym_type_in_parentheses, | 98 | lsym_type_in_parentheses, | |
99 | lsym_word, /* identifier, constant or string */ | 99 | lsym_word, /* identifier, constant or string */ | |
100 | lsym_funcname, /* name of a function being defined */ | 100 | lsym_funcname, /* name of a function being defined */ | |
101 | lsym_label_colon, /* the ':' after a label */ | 101 | lsym_label_colon, /* the ':' after a label */ | |
102 | lsym_other_colon, /* bit-fields, generic-association (C11), | 102 | lsym_other_colon, /* bit-fields, generic-association (C11), | |
103 | * enum-type-specifier (C23), | 103 | * enum-type-specifier (C23), | |
104 | * attribute-prefixed-token (C23), | 104 | * attribute-prefixed-token (C23), | |
105 | * pp-prefixed-parameter (C23 6.10) */ | 105 | * pp-prefixed-parameter (C23 6.10) */ | |
106 | lsym_semicolon, | 106 | lsym_semicolon, | |
107 | 107 | |||
108 | lsym_case, | 108 | lsym_case, | |
109 | lsym_default, | 109 | lsym_default, | |
110 | lsym_do, | 110 | lsym_do, | |
111 | lsym_else, | 111 | lsym_else, | |
112 | lsym_for, | 112 | lsym_for, | |
113 | lsym_if, | 113 | lsym_if, | |
114 | lsym_switch, | 114 | lsym_switch, | |
115 | lsym_while, | 115 | lsym_while, | |
116 | lsym_return, | 116 | lsym_return, | |
117 | } lexer_symbol; | 117 | } lexer_symbol; | |
118 | 118 | |||
119 | /* | 119 | /* | |
120 | * Structure of the source code, in terms of declarations, statements and | 120 | * Structure of the source code, in terms of declarations, statements and | |
121 | * braces; used to determine the indentation level of these parts. | 121 | * braces; used to determine the indentation level of these parts. | |
122 | */ | 122 | */ | |
123 | typedef enum parser_symbol { | 123 | typedef enum parser_symbol { | |
124 | psym_0, /* a placeholder; not stored on the stack */ | 124 | psym_0, /* a placeholder; not stored on the stack */ | |
125 | psym_lbrace_block, /* '{' for a block of code */ | 125 | psym_lbrace_block, /* '{' for a block of code */ | |
126 | psym_lbrace_struct, /* '{' in 'struct ... { ... }' */ | 126 | psym_lbrace_struct, /* '{' in 'struct ... { ... }' */ | |
127 | psym_lbrace_union, /* '{' in 'union ... { ... }' */ | 127 | psym_lbrace_union, /* '{' in 'union ... { ... }' */ | |
128 | psym_lbrace_enum, /* '{' in 'enum ... { ... }' */ | 128 | psym_lbrace_enum, /* '{' in 'enum ... { ... }' */ | |
129 | psym_rbrace, /* not stored on the stack */ | 129 | psym_rbrace, /* not stored on the stack */ | |
130 | psym_decl, | 130 | psym_decl, | |
131 | psym_stmt, | 131 | psym_stmt, | |
132 | psym_stmt_list, | 132 | psym_stmt_list, | |
133 | psym_for_exprs, /* 'for' '(' ... ')' */ | 133 | psym_for_exprs, /* 'for' '(' ... ')' */ | |
134 | psym_if_expr, /* 'if' '(' expr ')' */ | 134 | psym_if_expr, /* 'if' '(' expr ')' */ | |
135 | psym_if_expr_stmt, /* 'if' '(' expr ')' stmt */ | 135 | psym_if_expr_stmt, /* 'if' '(' expr ')' stmt */ | |
136 | psym_if_expr_stmt_else, /* 'if' '(' expr ')' stmt 'else' */ | 136 | psym_if_expr_stmt_else, /* 'if' '(' expr ')' stmt 'else' */ | |
137 | psym_else, /* 'else'; not stored on the stack */ | 137 | psym_else, /* 'else'; not stored on the stack */ | |
138 | psym_switch_expr, /* 'switch' '(' expr ')' */ | 138 | psym_switch_expr, /* 'switch' '(' expr ')' */ | |
139 | psym_do, /* 'do' */ | 139 | psym_do, /* 'do' */ | |
140 | psym_do_stmt, /* 'do' stmt */ | 140 | psym_do_stmt, /* 'do' stmt */ | |
141 | psym_while_expr, /* 'while' '(' expr ')' */ | 141 | psym_while_expr, /* 'while' '(' expr ')' */ | |
142 | } parser_symbol; | 142 | } parser_symbol; | |
143 | 143 | |||
144 | /* A range of characters, only null-terminated in debug mode. */ | 144 | /* A range of characters, only null-terminated in debug mode. */ | |
145 | struct buffer { | 145 | struct buffer { | |
146 | char *s; | 146 | char *s; | |
147 | size_t len; | 147 | size_t len; | |
148 | size_t cap; | 148 | size_t cap; | |
149 | }; | 149 | }; | |
150 | 150 | |||
151 | extern FILE *input; | 151 | extern FILE *input; | |
152 | extern FILE *output; | 152 | extern FILE *output; | |
153 | 153 | |||
154 | /* | 154 | /* | |
155 | * The current line from the input file, used by the lexer to generate tokens. | 155 | * The current line from the input file, used by the lexer to generate tokens. | |
156 | * To read from the line, start at inp_p and continue up to and including the | 156 | * To read from the line, start at inp_p and continue up to and including the | |
157 | * next '\n'. To read beyond the '\n', call inp_skip or inp_next, which will | 157 | * next '\n'. To read beyond the '\n', call inp_skip or inp_next, which will | |
158 | * make the next line available, invalidating any pointers into the previous | 158 | * make the next line available, invalidating any pointers into the previous | |
159 | * line. | 159 | * line. | |
160 | */ | 160 | */ | |
161 | extern struct buffer inp; | 161 | extern struct buffer inp; | |
162 | extern const char *inp_p; | 162 | extern const char *inp_p; | |
163 | 163 | |||
164 | extern struct buffer token; /* the current token to be processed, is | 164 | extern struct buffer token; /* the current token to be processed, is | |
165 | * typically copied to the buffer 'code', or in | 165 | * typically copied to the buffer 'code', or in | |
166 | * some cases to 'lab'. */ | 166 | * some cases to 'lab'. */ | |
167 | 167 | |||
168 | extern struct buffer lab; /* the label or preprocessor directive */ | 168 | extern struct buffer lab; /* the label or preprocessor directive */ | |
169 | extern struct buffer code; /* the main part of the current line of code, | 169 | extern struct buffer code; /* the main part of the current line of code, | |
170 | * containing declarations or statements */ | 170 | * containing declarations or statements */ | |
171 | extern struct buffer com; /* the trailing comment of the line, or the | 171 | extern struct buffer com; /* the trailing comment of the line, or the | |
172 | * start or end of a multi-line comment, or | 172 | * start or end of a multi-line comment, or | |
173 | * while in process_comment, a single line of a | 173 | * while in process_comment, a single line of a | |
174 | * multi-line comment */ | 174 | * multi-line comment */ | |
175 | 175 | |||
176 | extern struct options { | 176 | extern struct options { | |
177 | bool blank_line_around_conditional_compilation; | 177 | bool blank_line_around_conditional_compilation; | |
178 | bool blank_line_after_decl_at_top; /* this is vaguely similar to | 178 | bool blank_line_after_decl_at_top; /* this is vaguely similar to | |
179 | * blank_line_after_decl except | 179 | * blank_line_after_decl except | |
180 | * that it only applies to the | 180 | * that it only applies to the | |
181 | * first set of declarations in | 181 | * first set of declarations in | |
182 | * a procedure (just after the | 182 | * a procedure (just after the | |
183 | * first '{') and it causes a | 183 | * first '{') and it causes a | |
184 | * blank line to be generated | 184 | * blank line to be generated | |
185 | * even if there are no | 185 | * even if there are no | |
186 | * declarations */ | 186 | * declarations */ | |
187 | bool blank_line_after_decl; | 187 | bool blank_line_after_decl; | |
188 | bool blank_line_after_proc; | 188 | bool blank_line_after_proc; | |
189 | bool blank_line_before_block_comment; | 189 | bool blank_line_before_block_comment; | |
190 | bool break_after_comma; /* whether to add a line break after each | 190 | bool break_after_comma; /* whether to add a line break after each | |
191 | * declarator */ | 191 | * declarator */ | |
192 | bool brace_same_line; /* whether a brace should be on same line as an | 192 | bool brace_same_line; /* whether a brace should be on same line as an | |
193 | * if, while, etc. */ | 193 | * if, while, etc. */ | |
194 | bool blank_after_sizeof; | 194 | bool blank_after_sizeof; | |
195 | bool comment_delimiter_on_blank_line; | 195 | bool comment_delimiter_on_blank_line; | |
196 | int decl_comment_column; /* the column in which comments after | 196 | int decl_comment_column; /* the column in which comments after | |
197 | * declarations should be put */ | 197 | * declarations should be put */ | |
198 | bool cuddle_else; /* whether 'else' should cuddle up to '}' */ | 198 | bool cuddle_else; /* whether 'else' should cuddle up to '}' */ | |
199 | int continuation_indent; /* the indentation between the edge of | 199 | int continuation_indent; /* the indentation between the edge of | |
200 | * code and continuation lines */ | 200 | * code and continuation lines */ | |
201 | float case_indent; /* the distance (measured in indentation | 201 | float case_indent; /* the distance (measured in indentation | |
202 | * levels) to indent case labels from the | 202 | * levels) to indent case labels from the | |
203 | * switch statement */ | 203 | * switch statement */ | |
204 | int comment_column; /* the column in which comments to the right of | 204 | int comment_column; /* the column in which comments to the right of | |
205 | * code should start */ | 205 | * code should start */ | |
206 | int decl_indent; /* indentation of identifier in declaration */ | 206 | int decl_indent; /* indentation of identifier in declaration */ | |
207 | bool left_justify_decl; | 207 | bool left_justify_decl; | |
208 | int unindent_displace; /* comments not to the right of code will be | 208 | int unindent_displace; /* comments not to the right of code will be | |
209 | * placed this many indentation levels to the | 209 | * placed this many indentation levels to the | |
210 | * left of code */ | 210 | * left of code */ | |
211 | bool extra_expr_indent; /* whether continuation lines from the | 211 | bool extra_expr_indent; /* whether continuation lines from the | |
212 | * expression part of "if (e)", "while (e)", | 212 | * expression part of "if (e)", "while (e)", | |
213 | * "for (e; e; e)" should be indented an extra | 213 | * "for (e; e; e)" should be indented an extra | |
214 | * tab stop so that they are not confused with | 214 | * tab stop so that they are not confused with | |
215 | * the code that follows */ | 215 | * the code that follows */ | |
216 | bool else_if_in_same_line; | 216 | bool else_if_in_same_line; | |
217 | bool function_brace_split; /* split function declaration and brace | 217 | bool function_brace_split; /* split function declaration and brace | |
218 | * onto separate lines */ | 218 | * onto separate lines */ | |
219 | bool format_col1_comments; /* whether comments that start in | 219 | bool format_col1_comments; /* whether comments that start in | |
220 | * column 1 are to be reformatted (just | 220 | * column 1 are to be reformatted (just | |
221 | * like comments that begin in later | 221 | * like comments that begin in later | |
222 | * columns) */ | 222 | * columns) */ | |
223 | bool format_block_comments; /* whether to reformat comments that | 223 | bool format_block_comments; /* whether to reformat comments that | |
224 | * begin with '/ * \n' */ | 224 | * begin with '/ * \n' */ | |
225 | bool indent_parameters; | 225 | bool indent_parameters; | |
226 | int indent_size; /* the size of one indentation level */ | 226 | int indent_size; /* the size of one indentation level */ | |
227 | int block_comment_max_line_length; | 227 | int block_comment_max_line_length; | |
228 | int local_decl_indent; /* like decl_indent but for locals */ | 228 | int local_decl_indent; /* like decl_indent but for locals */ | |
229 | bool lineup_to_parens_always; /* whether to not(?) attempt to keep | 229 | bool lineup_to_parens_always; /* whether to not(?) attempt to keep | |
230 | * lined-up code within the margin */ | 230 | * lined-up code within the margin */ | |
231 | bool lineup_to_parens; /* whether continued code within parens will be | 231 | bool lineup_to_parens; /* whether continued code within parens will be | |
232 | * lined up to the open paren */ | 232 | * lined up to the open paren */ | |
233 | bool proc_calls_space; /* whether function calls look like: foo (bar) | 233 | bool proc_calls_space; /* whether function calls look like: foo (bar) | |
234 | * rather than foo(bar) */ | 234 | * rather than foo(bar) */ | |
235 | bool procnames_start_line; /* whether the names of functions being | 235 | bool procnames_start_line; /* whether the names of functions being | |
236 | * defined get placed in column 1 (i.e. | 236 | * defined get placed in column 1 (i.e. | |
237 | * a newline is placed between the type | 237 | * a newline is placed between the type | |
238 | * of the function and its name) */ | 238 | * of the function and its name) */ | |
239 | bool space_after_cast; /* "b = (int) a" vs. "b = (int)a" */ | 239 | bool space_after_cast; /* "b = (int) a" vs. "b = (int)a" */ | |
240 | bool star_comment_cont; /* whether comment continuation lines should | 240 | bool star_comment_cont; /* whether comment continuation lines should | |
241 | * have stars at the beginning of each line */ | 241 | * have stars at the beginning of each line */ | |
242 | bool swallow_optional_blank_lines; | 242 | bool swallow_optional_blank_lines; | |
243 | bool auto_typedefs; /* whether to recognize identifiers ending in | 243 | bool auto_typedefs; /* whether to recognize identifiers ending in | |
244 | * "_t" like typedefs */ | 244 | * "_t" like typedefs */ | |
245 | int tabsize; /* the size of a tab */ | 245 | int tabsize; /* the size of a tab */ | |
246 | int max_line_length; | 246 | int max_line_length; | |
247 | bool use_tabs; /* set true to use tabs for spacing, false uses | 247 | bool use_tabs; /* set true to use tabs for spacing, false uses | |
248 | * all spaces */ | 248 | * all spaces */ | |
249 | bool verbose; /* print configuration to stderr */ | 249 | bool verbose; /* print configuration to stderr */ | |
250 | } opt; | 250 | } opt; | |
251 | 251 | |||
252 | extern bool found_err; | 252 | extern bool found_err; | |
253 | extern bool had_eof; /* whether input is exhausted */ | 253 | extern bool had_eof; /* whether input is exhausted */ | |
254 | extern int line_no; /* the current input line number */ | 254 | extern int line_no; /* the current input line number */ | |
255 | extern enum indent_enabled { | 255 | extern enum indent_enabled { | |
256 | indent_on, | 256 | indent_on, | |
257 | indent_off, | 257 | indent_off, | |
258 | indent_last_off_line, | 258 | indent_last_off_line, | |
259 | } indent_enabled; | 259 | } indent_enabled; | |
260 | 260 | |||
261 | #define STACKSIZE 256 | 261 | #define STACKSIZE 256 | |
262 | 262 | |||
263 | /* Properties of each level of parentheses or brackets. */ | 263 | /* Properties of each level of parentheses or brackets. */ | |
264 | struct paren_level { | 264 | struct paren_level { | |
265 | int indent; /* indentation of the operand/argument, | 265 | int indent; /* indentation of the operand/argument, | |
266 | * relative to the enclosing statement; if | 266 | * relative to the enclosing statement; if | |
267 | * negative, reflected at -1 */ | 267 | * negative, reflected at -1 */ | |
268 | enum paren_level_cast { | 268 | enum paren_level_cast { | |
269 | cast_unknown, | 269 | cast_unknown, | |
270 | cast_maybe, | 270 | cast_maybe, | |
271 | cast_no, | 271 | cast_no, | |
272 | } cast; /* whether the parentheses form a type cast */ | 272 | } cast; /* whether the parentheses form a type cast */ | |
273 | }; | 273 | }; | |
274 | 274 | |||
275 | struct psym_stack { | 275 | struct psym_stack { | |
276 | int top; /* pointer to top of stack */ | 276 | int top; /* pointer to top of stack */ | |
277 | parser_symbol sym[STACKSIZE]; | 277 | parser_symbol sym[STACKSIZE]; | |
278 | int ind_level[STACKSIZE]; | 278 | int ind_level[STACKSIZE]; | |
279 | }; | 279 | }; | |
280 | 280 | |||
281 | /* | 281 | /* | |
282 | * The parser state determines the layout of the formatted text. | 282 | * The parser state determines the layout of the formatted text. | |
283 | * | 283 | * | |
284 | * At each '#if', the parser state is copied so that the corresponding '#else' | 284 | * At each '#if', the parser state is copied so that the corresponding '#else' | |
285 | * lines start in the same state. | 285 | * lines start in the same state. | |
286 | * | 286 | * | |
287 | * In a function body, the number of block braces determines the indentation | 287 | * In a function body, the number of block braces determines the indentation | |
288 | * of statements and declarations. | 288 | * of statements and declarations. | |
289 | * | 289 | * | |
290 | * In a statement, the number of parentheses or brackets determines the | 290 | * In a statement, the number of parentheses or brackets determines the | |
291 | * indentation of follow-up lines. | 291 | * indentation of follow-up lines. | |
292 | * | 292 | * | |
293 | * In an expression, the token type determine whether to put spaces around. | 293 | * In an expression, the token type determine whether to put spaces around. | |
294 | * | 294 | * | |
295 | * In a source file, the types of line determine the vertical spacing, such as | 295 | * In a source file, the types of line determine the vertical spacing, such as | |
296 | * around preprocessing directives or function bodies, or above block | 296 | * around preprocessing directives or function bodies, or above block | |
297 | * comments. | 297 | * comments. | |
298 | */ | 298 | */ | |
299 | extern struct parser_state { | 299 | extern struct parser_state { | |
300 | lexer_symbol prev_lsym; /* the previous token, but never comment, | 300 | lexer_symbol prev_lsym; /* the previous token, but never comment, | |
301 | * newline or preprocessing line */ | 301 | * newline or preprocessing line */ | |
302 | 302 | |||
303 | /* Token classification */ | 303 | /* Token classification */ | |
304 | 304 | |||
305 | bool in_stmt_or_decl; /* whether in a statement or a struct | 305 | bool in_stmt_or_decl; /* whether in a statement or a struct | |
306 | * declaration or a plain declaration */ | 306 | * declaration or a plain declaration */ | |
307 | bool in_decl; /* XXX: double-check the exact meaning */ | 307 | bool in_decl; /* XXX: double-check the exact meaning */ | |
308 | bool in_var_decl; /* starts at a type name or a '){' from a | 308 | bool in_var_decl; /* starts at a type name or a '){' from a | |
309 | * compound literal; ends at the '(' from a | 309 | * compound literal; ends at the '(' from a | |
310 | * function definition or a ';' outside '{}'; | 310 | * function definition or a ';' outside '{}'; | |
311 | * when active, '{}' form struct or union | 311 | * when active, '{}' form struct or union | |
312 | * declarations, ':' marks a bit-field, and '=' | 312 | * declarations, ':' marks a bit-field, and '=' | |
313 | * starts an initializer */ | 313 | * starts an initializer */ | |
314 | bool in_init; /* whether inside an initializer */ | 314 | bool in_init; /* whether inside an initializer */ | |
315 | int init_level; /* the number of '{}' in an initializer */ | 315 | int init_level; /* the number of '{}' in an initializer */ | |
316 | bool line_has_func_def; /* starts either at the 'name(' from a function | 316 | bool line_has_func_def; /* starts either at the 'name(' from a function | |
317 | * definition if it occurs at the beginning of | 317 | * definition if it occurs at the beginning of | |
318 | * a line, or at the first '*' from inside a | 318 | * a line, or at the first '*' from inside a | |
319 | * declaration when the line starts with words | 319 | * declaration when the line starts with words | |
320 | * followed by a '(' */ | 320 | * followed by a '(' */ | |
321 | bool in_func_def_params; /* for old-style functions */ | 321 | bool in_func_def_params; /* for old-style functions */ | |
322 | bool line_has_decl; /* whether this line of code has part of a | 322 | bool line_has_decl; /* whether this line of code has part of a | |
323 | * declaration on it; used for indenting | 323 | * declaration on it; used for indenting | |
324 | * comments */ | 324 | * comments */ | |
325 | parser_symbol lbrace_kind; /* the kind of brace to be pushed to | 325 | parser_symbol lbrace_kind; /* the kind of brace to be pushed to | |
326 | * the parser symbol stack next */ | 326 | * the parser symbol stack next */ | |
327 | parser_symbol spaced_expr_psym; /* the parser symbol to be shifted | 327 | parser_symbol spaced_expr_psym; /* the parser symbol to be shifted | |
328 | * after the parenthesized expression | 328 | * after the parenthesized expression | |
329 | * from a 'for', 'if', 'switch' or | 329 | * from a 'for', 'if', 'switch' or | |
330 | * 'while'; or psym_0 */ | 330 | * 'while'; or psym_0 */ | |
331 | bool seen_case; /* whether there was a 'case' or 'default', to | 331 | bool seen_case; /* whether there was a 'case' or 'default', to | |
332 | * properly space the following ':' */ | 332 | * properly space the following ':' */ | |
333 | bool prev_paren_was_cast; | 333 | bool prev_paren_was_cast; | |
334 | int quest_level; /* when this is positive, we have seen a '?' | 334 | int quest_level; /* when this is positive, we have seen a '?' | |
335 | * without the matching ':' in a '?:' | 335 | * without the matching ':' in a '?:' | |
336 | * expression */ | 336 | * expression */ | |
337 | 337 | |||
338 | /* Indentation of statements and declarations */ | 338 | /* Indentation of statements and declarations */ | |
339 | 339 | |||
340 | int ind_level; /* the indentation level for the line that is | 340 | int ind_level; /* the indentation level for the line that is | |
341 | * currently prepared for output */ | 341 | * currently prepared for output */ | |
342 | int ind_level_follow; /* the level to which ind_level should be set | 342 | int ind_level_follow; /* the level to which ind_level should be set | |
343 | * after the current line is printed */ | 343 | * after the current line is printed */ | |
344 | bool in_stmt_cont; /* whether the current line should have an | 344 | bool in_stmt_cont; /* whether the current line should have an | |
345 | * extra indentation level because we are in | 345 | * extra indentation level because we are in | |
346 | * the middle of a statement */ | 346 | * the middle of a statement */ | |
347 | int decl_level; /* current nesting level for a structure | 347 | int decl_level; /* current nesting level for a structure | |
348 | * declaration or an initializer */ | 348 | * declaration or an initializer */ | |
349 | int di_stack[20]; /* a stack of structure indentation levels */ | 349 | int di_stack[20]; /* a stack of structure indentation levels */ | |
350 | bool decl_indent_done; /* whether the indentation for a declaration | 350 | bool decl_indent_done; /* whether the indentation for a declaration | |
351 | * has been added to the code buffer. */ | 351 | * has been added to the code buffer. */ | |
352 | int decl_ind; /* current indentation for declarations */ | 352 | int decl_ind; /* current indentation for declarations */ | |
353 | bool tabs_to_var; /* true if using tabs to indent to var name */ | 353 | bool tabs_to_var; /* true if using tabs to indent to var name */ | |
354 | 354 | |||
355 | enum { | 355 | enum { | |
356 | eei_no, | 356 | eei_no, | |
357 | eei_maybe, | 357 | eei_maybe, | |
358 | eei_last | 358 | eei_last | |
359 | } extra_expr_indent; | 359 | } extra_expr_indent; | |
360 | 360 | |||
361 | struct psym_stack psyms; | 361 | struct psym_stack psyms; | |
362 | 362 | |||
363 | /* Spacing inside a statement or declaration */ | 363 | /* Spacing inside a statement or declaration */ | |
364 | 364 | |||
365 | bool next_unary; /* whether the following operator should be | 365 | bool next_unary; /* whether the following operator should be | |
366 | * unary; is used in declarations for '*', as | 366 | * unary; is used in declarations for '*', as | |
367 | * well as in expressions */ | 367 | * well as in expressions */ | |
368 | bool want_blank; /* whether the following token should be | 368 | bool want_blank; /* whether the following token should be | |
369 | * prefixed by a blank. (Said prefixing is | 369 | * prefixed by a blank. (Said prefixing is | |
370 | * ignored in some cases.) */ | 370 | * ignored in some cases.) */ | |
371 | int line_start_nparen; /* the number of parentheses or brackets that | 371 | int ind_paren_level; /* the number of parentheses or brackets that | |
372 | * were open at the beginning of the current | 372 | * is used for indenting a continuation line of | |
373 | * line; used to indent within statements, | 373 | * a declaration, initializer or statement */ | |
374 | * initializers and declarations */ | |||
375 | int nparen; /* the number of parentheses or brackets that | 374 | int nparen; /* the number of parentheses or brackets that | |
376 | * are currently open; used to indent the | 375 | * are currently open; used to indent the | |
377 | * remaining lines of the statement, | 376 | * remaining lines of the statement, | |
378 | * initializer or declaration */ | 377 | * initializer or declaration */ | |
379 | struct paren_level paren[20]; | 378 | struct paren_level paren[20]; | |
380 | 379 | |||
381 | /* Horizontal spacing for comments */ | 380 | /* Horizontal spacing for comments */ | |
382 | 381 | |||
383 | int comment_delta; /* used to set up indentation for all lines of | 382 | int comment_delta; /* used to set up indentation for all lines of | |
384 | * a boxed comment after the first one */ | 383 | * a boxed comment after the first one */ | |
385 | int n_comment_delta; /* remembers how many columns there were before | 384 | int n_comment_delta; /* remembers how many columns there were before | |
386 | * the start of a box comment so that | 385 | * the start of a box comment so that | |
387 | * forthcoming lines of the comment are | 386 | * forthcoming lines of the comment are | |
388 | * indented properly */ | 387 | * indented properly */ | |
389 | int com_ind; /* indentation of the current comment */ | 388 | int com_ind; /* indentation of the current comment */ | |
390 | 389 | |||
391 | /* Vertical spacing */ | 390 | /* Vertical spacing */ | |
392 | 391 | |||
393 | bool break_after_comma; /* whether to add a newline after the next | 392 | bool break_after_comma; /* whether to add a newline after the next | |
394 | * comma; used in declarations but not in | 393 | * comma; used in declarations but not in | |
395 | * initializer lists */ | 394 | * initializer lists */ | |
396 | bool force_nl; /* whether the next token is forced to go to a | 395 | bool force_nl; /* whether the next token is forced to go to a | |
397 | * new line; used after 'if (expr)' and in | 396 | * new line; used after 'if (expr)' and in | |
398 | * similar situations; tokens like '{' may | 397 | * similar situations; tokens like '{' may | |
399 | * ignore this */ | 398 | * ignore this */ | |
400 | 399 | |||
401 | enum declaration { | 400 | enum declaration { | |
402 | decl_no, /* no declaration anywhere nearby */ | 401 | decl_no, /* no declaration anywhere nearby */ | |
403 | decl_begin, /* collecting tokens of a declaration */ | 402 | decl_begin, /* collecting tokens of a declaration */ | |
404 | decl_end, /* finished a declaration */ | 403 | decl_end, /* finished a declaration */ | |
405 | } declaration; | 404 | } declaration; | |
406 | bool blank_line_after_decl; | 405 | bool blank_line_after_decl; | |
407 | 406 | |||
408 | /* Comments */ | 407 | /* Comments */ | |
409 | 408 | |||
410 | bool curr_col_1; /* whether the current token started in column | 409 | bool curr_col_1; /* whether the current token started in column | |
411 | * 1 of the original input */ | 410 | * 1 of the original input */ | |
412 | bool next_col_1; | 411 | bool next_col_1; | |
413 | } ps; | 412 | } ps; | |
414 | 413 | |||
415 | extern struct output_state { | 414 | extern struct output_state { | |
416 | enum line_kind { | 415 | enum line_kind { | |
417 | lk_other, | 416 | lk_other, | |
418 | lk_blank, | 417 | lk_blank, | |
419 | lk_if, /* #if, #ifdef, #ifndef */ | 418 | lk_if, /* #if, #ifdef, #ifndef */ | |
420 | lk_endif, /* #endif */ | 419 | lk_endif, /* #endif */ | |
421 | lk_stmt_head, /* the ')' of an incomplete statement such as | 420 | lk_stmt_head, /* the ')' of an incomplete statement such as | |
422 | * 'if (expr)' or 'for (expr; expr; expr)' */ | 421 | * 'if (expr)' or 'for (expr; expr; expr)' */ | |
423 | lk_func_end, /* the last '}' of a function body */ | 422 | lk_func_end, /* the last '}' of a function body */ | |
424 | lk_block_comment, | 423 | lk_block_comment, | |
425 | lk_case_or_default, | 424 | lk_case_or_default, | |
426 | } line_kind; /* kind of the line that is being prepared for | 425 | } line_kind; /* kind of the line that is being prepared for | |
427 | * output; is reset to lk_other each time after | 426 | * output; is reset to lk_other each time after | |
428 | * trying to send a line to the output, even if | 427 | * trying to send a line to the output, even if | |
429 | * that line was a suppressed blank line; used | 428 | * that line was a suppressed blank line; used | |
430 | * for inserting or removing blank lines */ | 429 | * for inserting or removing blank lines */ | |
431 | enum line_kind prev_line_kind; /* the kind of line that was actually | 430 | enum line_kind prev_line_kind; /* the kind of line that was actually | |
432 | * sent to the output */ | 431 | * sent to the output */ | |
433 | 432 | |||
434 | struct buffer indent_off_text; /* text from between 'INDENT OFF' and | 433 | struct buffer indent_off_text; /* text from between 'INDENT OFF' and | |
435 | * 'INDENT ON', both inclusive */ | 434 | * 'INDENT ON', both inclusive */ | |
436 | } out; | 435 | } out; | |
437 | 436 | |||
438 | 437 | |||
439 | #define array_length(array) (sizeof(array) / sizeof((array)[0])) | 438 | #define array_length(array) (sizeof(array) / sizeof((array)[0])) | |
440 | 439 | |||
441 | #ifdef debug | 440 | #ifdef debug | |
442 | void debug_printf(const char *, ...) __printflike(1, 2); | 441 | void debug_printf(const char *, ...) __printflike(1, 2); | |
443 | void debug_println(const char *, ...) __printflike(1, 2); | 442 | void debug_println(const char *, ...) __printflike(1, 2); | |
444 | void debug_blank_line(void); | 443 | void debug_blank_line(void); | |
445 | void debug_vis_range(const char *, const char *, size_t, const char *); | 444 | void debug_vis_range(const char *, const char *, size_t, const char *); | |
446 | void debug_parser_state(void); | 445 | void debug_parser_state(void); | |
447 | void debug_psyms_stack(const char *); | 446 | void debug_psyms_stack(const char *); | |
448 | void debug_print_buf(const char *, const struct buffer *); | 447 | void debug_print_buf(const char *, const struct buffer *); | |
449 | void debug_buffers(void); | 448 | void debug_buffers(void); | |
450 | extern const char *const lsym_name[]; | 449 | extern const char *const lsym_name[]; | |
451 | extern const char *const psym_name[]; | 450 | extern const char *const psym_name[]; | |
452 | extern const char *const paren_level_cast_name[]; | 451 | extern const char *const paren_level_cast_name[]; | |
453 | extern const char *const line_kind_name[]; | 452 | extern const char *const line_kind_name[]; | |
454 | #else | 453 | #else | |
455 | #define debug_noop() do { } while (false) | 454 | #define debug_noop() do { } while (false) | |
456 | #define debug_printf(fmt, ...) debug_noop() | 455 | #define debug_printf(fmt, ...) debug_noop() | |
457 | #define debug_println(fmt, ...) debug_noop() | 456 | #define debug_println(fmt, ...) debug_noop() | |
458 | #define debug_blank_line() debug_noop() | 457 | #define debug_blank_line() debug_noop() | |
459 | #define debug_vis_range(prefix, s, e, suffix) debug_noop() | 458 | #define debug_vis_range(prefix, s, e, suffix) debug_noop() | |
460 | #define debug_parser_state() debug_noop() | 459 | #define debug_parser_state() debug_noop() | |
461 | #define debug_psyms_stack(situation) debug_noop() | 460 | #define debug_psyms_stack(situation) debug_noop() | |
462 | #define debug_print_buf(name, buf) debug_noop() | 461 | #define debug_print_buf(name, buf) debug_noop() | |
463 | #define debug_buffers() debug_noop() | 462 | #define debug_buffers() debug_noop() | |
464 | #endif | 463 | #endif | |
465 | 464 | |||
466 | void register_typename(const char *); | 465 | void register_typename(const char *); | |
467 | int compute_code_indent(void); | 466 | int compute_code_indent(void); | |
468 | int compute_label_indent(void); | 467 | int compute_label_indent(void); | |
469 | int ind_add(int, const char *, size_t); | 468 | int ind_add(int, const char *, size_t); | |
470 | 469 | |||
471 | void inp_skip(void); | 470 | void inp_skip(void); | |
472 | char inp_next(void); | 471 | char inp_next(void); | |
473 | void finish_output(void); | 472 | void finish_output(void); | |
474 | 473 | |||
475 | lexer_symbol lexi(void); | 474 | lexer_symbol lexi(void); | |
476 | void diag(int, const char *, ...) __printflike(2, 3); | 475 | void diag(int, const char *, ...) __printflike(2, 3); | |
477 | void output_line(void); | 476 | void output_line(void); | |
478 | void inp_read_line(void); | 477 | void inp_read_line(void); | |
479 | void parse(parser_symbol); | 478 | void parse(parser_symbol); | |
480 | void process_comment(void); | 479 | void process_comment(void); | |
481 | void set_option(const char *, const char *); | 480 | void set_option(const char *, const char *); | |
482 | void load_profile_files(const char *); | 481 | void load_profile_files(const char *); | |
483 | 482 | |||
484 | void *nonnull(void *); | 483 | void *nonnull(void *); | |
485 | 484 | |||
486 | void buf_add_char(struct buffer *, char); | 485 | void buf_add_char(struct buffer *, char); | |
487 | void buf_add_chars(struct buffer *, const char *, size_t); | 486 | void buf_add_chars(struct buffer *, const char *, size_t); | |
488 | 487 | |||
489 | static inline bool | 488 | static inline bool | |
490 | ch_isalnum(char ch) | 489 | ch_isalnum(char ch) | |
491 | { | 490 | { | |
492 | return isalnum((unsigned char)ch) != 0; | 491 | return isalnum((unsigned char)ch) != 0; | |
493 | } | 492 | } | |
494 | 493 | |||
495 | static inline bool | 494 | static inline bool | |
496 | ch_isalpha(char ch) | 495 | ch_isalpha(char ch) | |
497 | { | 496 | { | |
498 | return isalpha((unsigned char)ch) != 0; | 497 | return isalpha((unsigned char)ch) != 0; | |
499 | } | 498 | } | |
500 | 499 | |||
501 | static inline bool | 500 | static inline bool | |
502 | ch_isblank(char ch) | 501 | ch_isblank(char ch) | |
503 | { | 502 | { | |
504 | return ch == ' ' || ch == '\t'; | 503 | return ch == ' ' || ch == '\t'; | |
505 | } | 504 | } | |
506 | 505 | |||
507 | static inline bool | 506 | static inline bool | |
508 | ch_isdigit(char ch) | 507 | ch_isdigit(char ch) | |
509 | { | 508 | { | |
510 | return '0' <= ch && ch <= '9'; | 509 | return '0' <= ch && ch <= '9'; | |
511 | } | 510 | } | |
512 | 511 | |||
513 | static inline bool | 512 | static inline bool | |
514 | ch_isspace(char ch) | 513 | ch_isspace(char ch) | |
515 | { | 514 | { | |
516 | return isspace((unsigned char)ch) != 0; | 515 | return isspace((unsigned char)ch) != 0; | |
517 | } | 516 | } | |
518 | 517 | |||
519 | static inline int | 518 | static inline int | |
520 | next_tab(int ind) | 519 | next_tab(int ind) | |
521 | { | 520 | { | |
522 | return ind - ind % opt.tabsize + opt.tabsize; | 521 | return ind - ind % opt.tabsize + opt.tabsize; | |
523 | } | 522 | } | |
524 | 523 | |||
525 | #ifdef debug | 524 | #ifdef debug | |
526 | void buf_terminate(struct buffer *); | 525 | void buf_terminate(struct buffer *); | |
527 | #else | 526 | #else | |
528 | #define buf_terminate(buf) debug_noop() | 527 | #define buf_terminate(buf) debug_noop() | |
529 | #endif | 528 | #endif | |
530 | 529 | |||
531 | static inline void | 530 | static inline void | |
532 | buf_clear(struct buffer *buf) | 531 | buf_clear(struct buffer *buf) | |
533 | { | 532 | { | |
534 | buf->len = 0; | 533 | buf->len = 0; | |
535 | buf_terminate(buf); | 534 | buf_terminate(buf); | |
536 | } | 535 | } |
--- src/usr.bin/indent/io.c 2023/06/10 16:43:56 1.216
+++ src/usr.bin/indent/io.c 2023/06/10 21:36:38 1.217
@@ -1,421 +1,421 @@ | @@ -1,421 +1,421 @@ | |||
1 | /* $NetBSD: io.c,v 1.216 2023/06/10 16:43:56 rillig Exp $ */ | 1 | /* $NetBSD: io.c,v 1.217 2023/06/10 21:36:38 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 | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
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: io.c,v 1.216 2023/06/10 16:43:56 rillig Exp $"); | 41 | __RCSID("$NetBSD: io.c,v 1.217 2023/06/10 21:36:38 rillig Exp $"); | |
42 | 42 | |||
43 | #include <stdio.h> | 43 | #include <stdio.h> | |
44 | 44 | |||
45 | #include "indent.h" | 45 | #include "indent.h" | |
46 | 46 | |||
47 | struct buffer inp; | 47 | struct buffer inp; | |
48 | const char *inp_p; | 48 | const char *inp_p; | |
49 | 49 | |||
50 | struct output_state out; | 50 | struct output_state out; | |
51 | enum indent_enabled indent_enabled; | 51 | enum indent_enabled indent_enabled; | |
52 | static int out_ind; /* width of the line that is being written */ | 52 | static int out_ind; /* width of the line that is being written */ | |
53 | static unsigned newlines = 2; /* the total of written and buffered newlines; | 53 | static unsigned newlines = 2; /* the total of written and buffered newlines; | |
54 | * 0 in the middle of a line, 1 after a single | 54 | * 0 in the middle of a line, 1 after a single | |
55 | * finished line, anything > 1 are trailing | 55 | * finished line, anything > 1 are trailing | |
56 | * blank lines */ | 56 | * blank lines */ | |
57 | static unsigned buffered_newlines; /* not yet written */ | 57 | static unsigned buffered_newlines; /* not yet written */ | |
58 | static int paren_indent; | 58 | static int paren_indent; | |
59 | 59 | |||
60 | 60 | |||
61 | static void | 61 | static void | |
62 | inp_read_next_line(FILE *f) | 62 | inp_read_next_line(FILE *f) | |
63 | { | 63 | { | |
64 | buf_clear(&inp); | 64 | buf_clear(&inp); | |
65 | 65 | |||
66 | for (;;) { | 66 | for (;;) { | |
67 | int ch = getc(f); | 67 | int ch = getc(f); | |
68 | if (ch == EOF) { | 68 | if (ch == EOF) { | |
69 | if (indent_enabled == indent_on) { | 69 | if (indent_enabled == indent_on) { | |
70 | buf_add_char(&inp, ' '); | 70 | buf_add_char(&inp, ' '); | |
71 | buf_add_char(&inp, '\n'); | 71 | buf_add_char(&inp, '\n'); | |
72 | } | 72 | } | |
73 | had_eof = true; | 73 | had_eof = true; | |
74 | break; | 74 | break; | |
75 | } | 75 | } | |
76 | 76 | |||
77 | if (ch != '\0') | 77 | if (ch != '\0') | |
78 | buf_add_char(&inp, (char)ch); | 78 | buf_add_char(&inp, (char)ch); | |
79 | if (ch == '\n') | 79 | if (ch == '\n') | |
80 | break; | 80 | break; | |
81 | } | 81 | } | |
82 | buf_terminate(&inp); | 82 | buf_terminate(&inp); | |
83 | inp_p = inp.s; | 83 | inp_p = inp.s; | |
84 | } | 84 | } | |
85 | 85 | |||
86 | void | 86 | void | |
87 | inp_read_line(void) | 87 | inp_read_line(void) | |
88 | { | 88 | { | |
89 | if (indent_enabled == indent_on) | 89 | if (indent_enabled == indent_on) | |
90 | buf_clear(&out.indent_off_text); | 90 | buf_clear(&out.indent_off_text); | |
91 | buf_add_chars(&out.indent_off_text, inp.s, inp.len); | 91 | buf_add_chars(&out.indent_off_text, inp.s, inp.len); | |
92 | inp_read_next_line(input); | 92 | inp_read_next_line(input); | |
93 | } | 93 | } | |
94 | 94 | |||
95 | void | 95 | void | |
96 | inp_skip(void) | 96 | inp_skip(void) | |
97 | { | 97 | { | |
98 | inp_p++; | 98 | inp_p++; | |
99 | if ((size_t)(inp_p - inp.s) >= inp.len) | 99 | if ((size_t)(inp_p - inp.s) >= inp.len) | |
100 | inp_read_line(); | 100 | inp_read_line(); | |
101 | } | 101 | } | |
102 | 102 | |||
103 | char | 103 | char | |
104 | inp_next(void) | 104 | inp_next(void) | |
105 | { | 105 | { | |
106 | char ch = inp_p[0]; | 106 | char ch = inp_p[0]; | |
107 | inp_skip(); | 107 | inp_skip(); | |
108 | return ch; | 108 | return ch; | |
109 | } | 109 | } | |
110 | 110 | |||
111 | 111 | |||
112 | static void | 112 | static void | |
113 | add_buffered_newline(void) | 113 | add_buffered_newline(void) | |
114 | { | 114 | { | |
115 | buffered_newlines++; | 115 | buffered_newlines++; | |
116 | newlines++; | 116 | newlines++; | |
117 | out_ind = 0; | 117 | out_ind = 0; | |
118 | } | 118 | } | |
119 | 119 | |||
120 | static void | 120 | static void | |
121 | write_buffered_newlines(void) | 121 | write_buffered_newlines(void) | |
122 | { | 122 | { | |
123 | for (; buffered_newlines > 0; buffered_newlines--) { | 123 | for (; buffered_newlines > 0; buffered_newlines--) { | |
124 | fputc('\n', output); | 124 | fputc('\n', output); | |
125 | debug_println("write_newline"); | 125 | debug_println("write_newline"); | |
126 | } | 126 | } | |
127 | } | 127 | } | |
128 | 128 | |||
129 | static void | 129 | static void | |
130 | write_range(const char *s, size_t len) | 130 | write_range(const char *s, size_t len) | |
131 | { | 131 | { | |
132 | write_buffered_newlines(); | 132 | write_buffered_newlines(); | |
133 | fwrite(s, 1, len, output); | 133 | fwrite(s, 1, len, output); | |
134 | debug_vis_range("write_range \"", s, len, "\"\n"); | 134 | debug_vis_range("write_range \"", s, len, "\"\n"); | |
135 | for (size_t i = 0; i < len; i++) | 135 | for (size_t i = 0; i < len; i++) | |
136 | newlines = s[i] == '\n' ? newlines + 1 : 0; | 136 | newlines = s[i] == '\n' ? newlines + 1 : 0; | |
137 | out_ind = ind_add(out_ind, s, len); | 137 | out_ind = ind_add(out_ind, s, len); | |
138 | } | 138 | } | |
139 | 139 | |||
140 | static void | 140 | static void | |
141 | write_indent(int new_ind) | 141 | write_indent(int new_ind) | |
142 | { | 142 | { | |
143 | write_buffered_newlines(); | 143 | write_buffered_newlines(); | |
144 | 144 | |||
145 | int ind = out_ind; | 145 | int ind = out_ind; | |
146 | 146 | |||
147 | if (opt.use_tabs) { | 147 | if (opt.use_tabs) { | |
148 | int n = new_ind / opt.tabsize - ind / opt.tabsize; | 148 | int n = new_ind / opt.tabsize - ind / opt.tabsize; | |
149 | if (n > 0) { | 149 | if (n > 0) { | |
150 | ind = ind - ind % opt.tabsize + n * opt.tabsize; | 150 | ind = ind - ind % opt.tabsize + n * opt.tabsize; | |
151 | while (n-- > 0) | 151 | while (n-- > 0) | |
152 | fputc('\t', output); | 152 | fputc('\t', output); | |
153 | newlines = 0; | 153 | newlines = 0; | |
154 | } | 154 | } | |
155 | } | 155 | } | |
156 | 156 | |||
157 | for (; ind < new_ind; ind++) { | 157 | for (; ind < new_ind; ind++) { | |
158 | fputc(' ', output); | 158 | fputc(' ', output); | |
159 | newlines = 0; | 159 | newlines = 0; | |
160 | } | 160 | } | |
161 | 161 | |||
162 | debug_println("write_indent %d", ind); | 162 | debug_println("write_indent %d", ind); | |
163 | out_ind = ind; | 163 | out_ind = ind; | |
164 | } | 164 | } | |
165 | 165 | |||
166 | static bool | 166 | static bool | |
167 | want_blank_line(void) | 167 | want_blank_line(void) | |
168 | { | 168 | { | |
169 | debug_println("%s: %s -> %s", __func__, | 169 | debug_println("%s: %s -> %s", __func__, | |
170 | line_kind_name[out.prev_line_kind], line_kind_name[out.line_kind]); | 170 | line_kind_name[out.prev_line_kind], line_kind_name[out.line_kind]); | |
171 | 171 | |||
172 | if (ps.blank_line_after_decl && ps.declaration == decl_no) { | 172 | if (ps.blank_line_after_decl && ps.declaration == decl_no) { | |
173 | ps.blank_line_after_decl = false; | 173 | ps.blank_line_after_decl = false; | |
174 | return true; | 174 | return true; | |
175 | } | 175 | } | |
176 | if (opt.blank_line_around_conditional_compilation) { | 176 | if (opt.blank_line_around_conditional_compilation) { | |
177 | if (out.prev_line_kind != lk_if && out.line_kind == lk_if) | 177 | if (out.prev_line_kind != lk_if && out.line_kind == lk_if) | |
178 | return true; | 178 | return true; | |
179 | if (out.prev_line_kind == lk_endif | 179 | if (out.prev_line_kind == lk_endif | |
180 | && out.line_kind != lk_endif) | 180 | && out.line_kind != lk_endif) | |
181 | return true; | 181 | return true; | |
182 | } | 182 | } | |
183 | if (opt.blank_line_after_proc && out.prev_line_kind == lk_func_end | 183 | if (opt.blank_line_after_proc && out.prev_line_kind == lk_func_end | |
184 | && out.line_kind != lk_endif) | 184 | && out.line_kind != lk_endif) | |
185 | return true; | 185 | return true; | |
186 | if (opt.blank_line_before_block_comment | 186 | if (opt.blank_line_before_block_comment | |
187 | && out.line_kind == lk_block_comment) | 187 | && out.line_kind == lk_block_comment) | |
188 | return true; | 188 | return true; | |
189 | return false; | 189 | return false; | |
190 | } | 190 | } | |
191 | 191 | |||
192 | static bool | 192 | static bool | |
193 | is_blank_line_optional(void) | 193 | is_blank_line_optional(void) | |
194 | { | 194 | { | |
195 | if (out.prev_line_kind == lk_stmt_head) | 195 | if (out.prev_line_kind == lk_stmt_head) | |
196 | return newlines >= 1; | 196 | return newlines >= 1; | |
197 | if (ps.psyms.top >= 2) | 197 | if (ps.psyms.top >= 2) | |
198 | return newlines >= 2; | 198 | return newlines >= 2; | |
199 | return newlines >= 3; | 199 | return newlines >= 3; | |
200 | } | 200 | } | |
201 | 201 | |||
202 | static int | 202 | static int | |
203 | compute_case_label_indent(void) | 203 | compute_case_label_indent(void) | |
204 | { | 204 | { | |
205 | int i = ps.psyms.top; | 205 | int i = ps.psyms.top; | |
206 | while (i > 0 && ps.psyms.sym[i] != psym_switch_expr) | 206 | while (i > 0 && ps.psyms.sym[i] != psym_switch_expr) | |
207 | i--; | 207 | i--; | |
208 | float case_ind = (float)ps.psyms.ind_level[i] + opt.case_indent; | 208 | float case_ind = (float)ps.psyms.ind_level[i] + opt.case_indent; | |
209 | return (int)(case_ind * (float)opt.indent_size); | 209 | return (int)(case_ind * (float)opt.indent_size); | |
210 | } | 210 | } | |
211 | 211 | |||
212 | int | 212 | int | |
213 | compute_label_indent(void) | 213 | compute_label_indent(void) | |
214 | { | 214 | { | |
215 | if (out.line_kind == lk_case_or_default) | 215 | if (out.line_kind == lk_case_or_default) | |
216 | return compute_case_label_indent(); | 216 | return compute_case_label_indent(); | |
217 | if (lab.s[0] == '#') | 217 | if (lab.s[0] == '#') | |
218 | return 0; | 218 | return 0; | |
219 | return opt.indent_size * (ps.ind_level - 2); | 219 | return opt.indent_size * (ps.ind_level - 2); | |
220 | } | 220 | } | |
221 | 221 | |||
222 | static void | 222 | static void | |
223 | output_line_label(void) | 223 | output_line_label(void) | |
224 | { | 224 | { | |
225 | write_indent(compute_label_indent()); | 225 | write_indent(compute_label_indent()); | |
226 | write_range(lab.s, lab.len); | 226 | write_range(lab.s, lab.len); | |
227 | } | 227 | } | |
228 | 228 | |||
229 | static int | 229 | static int | |
230 | compute_lined_up_code_indent(int base_ind) | 230 | compute_lined_up_code_indent(int base_ind) | |
231 | { | 231 | { | |
232 | int ind = paren_indent; | 232 | int ind = paren_indent; | |
233 | int overflow = ind_add(ind, code.s, code.len) - opt.max_line_length; | 233 | int overflow = ind_add(ind, code.s, code.len) - opt.max_line_length; | |
234 | if (overflow >= 0 | 234 | if (overflow >= 0 | |
235 | && ind_add(base_ind, code.s, code.len) < opt.max_line_length) { | 235 | && ind_add(base_ind, code.s, code.len) < opt.max_line_length) { | |
236 | ind -= overflow + 2; | 236 | ind -= overflow + 2; | |
237 | if (ind < base_ind) | 237 | if (ind < base_ind) | |
238 | ind = base_ind; | 238 | ind = base_ind; | |
239 | } | 239 | } | |
240 | 240 | |||
241 | if (ps.extra_expr_indent != eei_no | 241 | if (ps.extra_expr_indent != eei_no | |
242 | && ind == base_ind + opt.indent_size) | 242 | && ind == base_ind + opt.indent_size) | |
243 | ind += opt.continuation_indent; | 243 | ind += opt.continuation_indent; | |
244 | return ind; | 244 | return ind; | |
245 | } | 245 | } | |
246 | 246 | |||
247 | int | 247 | int | |
248 | compute_code_indent(void) | 248 | compute_code_indent(void) | |
249 | { | 249 | { | |
250 | int base_ind = ps.ind_level * opt.indent_size; | 250 | int base_ind = ps.ind_level * opt.indent_size; | |
251 | 251 | |||
252 | if (ps.line_start_nparen == 0) { | 252 | if (ps.ind_paren_level == 0) { | |
253 | if (ps.psyms.top >= 1 | 253 | if (ps.psyms.top >= 1 | |
254 | && ps.psyms.sym[ps.psyms.top - 1] == psym_lbrace_enum) | 254 | && ps.psyms.sym[ps.psyms.top - 1] == psym_lbrace_enum) | |
255 | return base_ind; | 255 | return base_ind; | |
256 | if (ps.in_stmt_cont) | 256 | if (ps.in_stmt_cont) | |
257 | return base_ind + opt.continuation_indent; | 257 | return base_ind + opt.continuation_indent; | |
258 | return base_ind; | 258 | return base_ind; | |
259 | } | 259 | } | |
260 | 260 | |||
261 | if (opt.lineup_to_parens) { | 261 | if (opt.lineup_to_parens) { | |
262 | if (opt.lineup_to_parens_always) | 262 | if (opt.lineup_to_parens_always) | |
263 | return paren_indent; | 263 | return paren_indent; | |
264 | return compute_lined_up_code_indent(base_ind); | 264 | return compute_lined_up_code_indent(base_ind); | |
265 | } | 265 | } | |
266 | 266 | |||
267 | int rel_ind = opt.continuation_indent * ps.line_start_nparen; | 267 | int rel_ind = opt.continuation_indent * ps.ind_paren_level; | |
268 | if (ps.extra_expr_indent != eei_no && rel_ind == opt.indent_size) | 268 | if (ps.extra_expr_indent != eei_no && rel_ind == opt.indent_size) | |
269 | rel_ind += opt.continuation_indent; | 269 | rel_ind += opt.continuation_indent; | |
270 | return base_ind + rel_ind; | 270 | return base_ind + rel_ind; | |
271 | } | 271 | } | |
272 | 272 | |||
273 | static void | 273 | static void | |
274 | output_line_code(void) | 274 | output_line_code(void) | |
275 | { | 275 | { | |
276 | int target_ind = compute_code_indent(); | 276 | int target_ind = compute_code_indent(); | |
277 | for (int i = 0; i < ps.nparen; i++) { | 277 | for (int i = 0; i < ps.nparen; i++) { | |
278 | int paren_ind = ps.paren[i].indent; | 278 | int paren_ind = ps.paren[i].indent; | |
279 | if (paren_ind >= 0) { | 279 | if (paren_ind >= 0) { | |
280 | ps.paren[i].indent = -1 - (paren_ind + target_ind); | 280 | ps.paren[i].indent = -1 - (paren_ind + target_ind); | |
281 | debug_println( | 281 | debug_println( | |
282 | "setting paren_indents[%d] from %d to %d " | 282 | "setting paren_indents[%d] from %d to %d " | |
283 | "for column %d", | 283 | "for column %d", | |
284 | i, paren_ind, ps.paren[i].indent, target_ind + 1); | 284 | i, paren_ind, ps.paren[i].indent, target_ind + 1); | |
285 | } | 285 | } | |
286 | } | 286 | } | |
287 | 287 | |||
288 | if (lab.len > 0 && target_ind <= out_ind) | 288 | if (lab.len > 0 && target_ind <= out_ind) | |
289 | write_range(" ", 1); | 289 | write_range(" ", 1); | |
290 | write_indent(target_ind); | 290 | write_indent(target_ind); | |
291 | write_range(code.s, code.len); | 291 | write_range(code.s, code.len); | |
292 | } | 292 | } | |
293 | 293 | |||
294 | static void | 294 | static void | |
295 | output_comment(void) | 295 | output_comment(void) | |
296 | { | 296 | { | |
297 | int target_ind = ps.com_ind + ps.comment_delta; | 297 | int target_ind = ps.com_ind + ps.comment_delta; | |
298 | const char *p; | 298 | const char *p; | |
299 | 299 | |||
300 | /* consider original indentation in case this is a box comment */ | 300 | /* consider original indentation in case this is a box comment */ | |
301 | for (p = com.s; *p == '\t'; p++) | 301 | for (p = com.s; *p == '\t'; p++) | |
302 | target_ind += opt.tabsize; | 302 | target_ind += opt.tabsize; | |
303 | 303 | |||
304 | for (; target_ind < 0; p++) { | 304 | for (; target_ind < 0; p++) { | |
305 | if (*p == ' ') | 305 | if (*p == ' ') | |
306 | target_ind++; | 306 | target_ind++; | |
307 | else if (*p == '\t') | 307 | else if (*p == '\t') | |
308 | target_ind = next_tab(target_ind); | 308 | target_ind = next_tab(target_ind); | |
309 | else { | 309 | else { | |
310 | target_ind = 0; | 310 | target_ind = 0; | |
311 | break; | 311 | break; | |
312 | } | 312 | } | |
313 | } | 313 | } | |
314 | 314 | |||
315 | if (out_ind > target_ind) | 315 | if (out_ind > target_ind) | |
316 | add_buffered_newline(); | 316 | add_buffered_newline(); | |
317 | 317 | |||
318 | while (com.s + com.len > p && ch_isspace(com.s[com.len - 1])) | 318 | while (com.s + com.len > p && ch_isspace(com.s[com.len - 1])) | |
319 | com.len--; | 319 | com.len--; | |
320 | buf_terminate(&com); | 320 | buf_terminate(&com); | |
321 | 321 | |||
322 | write_indent(target_ind); | 322 | write_indent(target_ind); | |
323 | write_range(p, com.len - (size_t)(p - com.s)); | 323 | write_range(p, com.len - (size_t)(p - com.s)); | |
324 | 324 | |||
325 | ps.comment_delta = ps.n_comment_delta; | 325 | ps.comment_delta = ps.n_comment_delta; | |
326 | } | 326 | } | |
327 | 327 | |||
328 | static void | 328 | static void | |
329 | output_indented_line(void) | 329 | output_indented_line(void) | |
330 | { | 330 | { | |
331 | if (lab.len == 0 && code.len == 0 && com.len == 0) | 331 | if (lab.len == 0 && code.len == 0 && com.len == 0) | |
332 | out.line_kind = lk_blank; | 332 | out.line_kind = lk_blank; | |
333 | 333 | |||
334 | if (want_blank_line() && newlines < 2 | 334 | if (want_blank_line() && newlines < 2 | |
335 | && out.line_kind != lk_blank) | 335 | && out.line_kind != lk_blank) | |
336 | add_buffered_newline(); | 336 | add_buffered_newline(); | |
337 | 337 | |||
338 | /* This kludge aligns function definitions correctly. */ | 338 | /* This kludge aligns function definitions correctly. */ | |
339 | if (ps.ind_level == 0) | 339 | if (ps.ind_level == 0) | |
340 | ps.in_stmt_cont = false; | 340 | ps.in_stmt_cont = false; | |
341 | 341 | |||
342 | if (opt.blank_line_after_decl && ps.declaration == decl_end | 342 | if (opt.blank_line_after_decl && ps.declaration == decl_end | |
343 | && ps.psyms.top > 1) { | 343 | && ps.psyms.top > 1) { | |
344 | ps.declaration = decl_no; | 344 | ps.declaration = decl_no; | |
345 | ps.blank_line_after_decl = true; | 345 | ps.blank_line_after_decl = true; | |
346 | } | 346 | } | |
347 | 347 | |||
348 | if (opt.swallow_optional_blank_lines | 348 | if (opt.swallow_optional_blank_lines | |
349 | && out.line_kind == lk_blank | 349 | && out.line_kind == lk_blank | |
350 | && is_blank_line_optional()) | 350 | && is_blank_line_optional()) | |
351 | return; | 351 | return; | |
352 | 352 | |||
353 | if (lab.len > 0) | 353 | if (lab.len > 0) | |
354 | output_line_label(); | 354 | output_line_label(); | |
355 | if (code.len > 0) | 355 | if (code.len > 0) | |
356 | output_line_code(); | 356 | output_line_code(); | |
357 | if (com.len > 0) | 357 | if (com.len > 0) | |
358 | output_comment(); | 358 | output_comment(); | |
359 | add_buffered_newline(); | 359 | add_buffered_newline(); | |
360 | if (out.line_kind != lk_blank) | 360 | if (out.line_kind != lk_blank) | |
361 | write_buffered_newlines(); | 361 | write_buffered_newlines(); | |
362 | 362 | |||
363 | out.prev_line_kind = out.line_kind; | 363 | out.prev_line_kind = out.line_kind; | |
364 | } | 364 | } | |
365 | 365 | |||
366 | /* | 366 | /* | |
367 | * Write a line of formatted source to the output file. The line consists of | 367 | * Write a line of formatted source to the output file. The line consists of | |
368 | * the label, the code and the comment. | 368 | * the label, the code and the comment. | |
369 | */ | 369 | */ | |
370 | void | 370 | void | |
371 | output_line(void) | 371 | output_line(void) | |
372 | { | 372 | { | |
373 | debug_blank_line(); | 373 | debug_blank_line(); | |
374 | debug_printf("%s", __func__); | 374 | debug_printf("%s", __func__); | |
375 | debug_buffers(); | 375 | debug_buffers(); | |
376 | 376 | |||
377 | if (indent_enabled == indent_on) | 377 | if (indent_enabled == indent_on) | |
378 | output_indented_line(); | 378 | output_indented_line(); | |
379 | else if (indent_enabled == indent_last_off_line) { | 379 | else if (indent_enabled == indent_last_off_line) { | |
380 | indent_enabled = indent_on; | 380 | indent_enabled = indent_on; | |
381 | write_range(out.indent_off_text.s, out.indent_off_text.len); | 381 | write_range(out.indent_off_text.s, out.indent_off_text.len); | |
382 | buf_clear(&out.indent_off_text); | 382 | buf_clear(&out.indent_off_text); | |
383 | } | 383 | } | |
384 | 384 | |||
385 | buf_clear(&lab); | 385 | buf_clear(&lab); | |
386 | buf_clear(&code); | 386 | buf_clear(&code); | |
387 | buf_clear(&com); | 387 | buf_clear(&com); | |
388 | 388 | |||
389 | ps.line_has_decl = ps.in_decl; | 389 | ps.line_has_decl = ps.in_decl; | |
390 | ps.line_has_func_def = false; | 390 | ps.line_has_func_def = false; | |
391 | ps.in_stmt_cont = ps.in_stmt_or_decl | 391 | ps.in_stmt_cont = ps.in_stmt_or_decl | |
392 | && (!ps.in_decl || ps.in_init) | 392 | && (!ps.in_decl || ps.in_init) | |
393 | && ps.init_level == 0; | 393 | && ps.init_level == 0; | |
394 | ps.decl_indent_done = false; | 394 | ps.decl_indent_done = false; | |
395 | if (ps.extra_expr_indent == eei_last) | 395 | if (ps.extra_expr_indent == eei_last) | |
396 | ps.extra_expr_indent = eei_no; | 396 | ps.extra_expr_indent = eei_no; | |
397 | if (!(ps.psyms.sym[ps.psyms.top] == psym_if_expr_stmt_else | 397 | if (!(ps.psyms.sym[ps.psyms.top] == psym_if_expr_stmt_else | |
398 | && ps.nparen > 0)) | 398 | && ps.nparen > 0)) | |
399 | ps.ind_level = ps.ind_level_follow; | 399 | ps.ind_level = ps.ind_level_follow; | |
400 | ps.line_start_nparen = ps.nparen; | 400 | ps.ind_paren_level = ps.nparen; | |
401 | ps.want_blank = false; | 401 | ps.want_blank = false; | |
402 | 402 | |||
403 | if (ps.nparen > 0) { | 403 | if (ps.nparen > 0) { | |
404 | /* TODO: explain what negative indentation means */ | 404 | /* TODO: explain what negative indentation means */ | |
405 | paren_indent = -1 - ps.paren[ps.nparen - 1].indent; | 405 | paren_indent = -1 - ps.paren[ps.nparen - 1].indent; | |
406 | debug_println("paren_indent is now %d", paren_indent); | 406 | debug_println("paren_indent is now %d", paren_indent); | |
407 | } | 407 | } | |
408 | 408 | |||
409 | out.line_kind = lk_other; | 409 | out.line_kind = lk_other; | |
410 | } | 410 | } | |
411 | 411 | |||
412 | void | 412 | void | |
413 | finish_output(void) | 413 | finish_output(void) | |
414 | { | 414 | { | |
415 | output_line(); | 415 | output_line(); | |
416 | if (indent_enabled != indent_on) { | 416 | if (indent_enabled != indent_on) { | |
417 | indent_enabled = indent_last_off_line; | 417 | indent_enabled = indent_last_off_line; | |
418 | output_line(); | 418 | output_line(); | |
419 | } | 419 | } | |
420 | fflush(output); | 420 | fflush(output); | |
421 | } | 421 | } |