Fri Jun 16 14:12:10 2023 UTC ()
indent: improve heuristics for cast expressions


(rillig)
diff -r1.6 -r1.7 src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c
diff -r1.375 -r1.376 src/usr.bin/indent/indent.c

cvs diff -r1.6 -r1.7 src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c (switch to unified diff)

--- src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c 2023/06/16 13:43:30 1.6
+++ src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c 2023/06/16 14:12:10 1.7
@@ -1,77 +1,76 @@ @@ -1,77 +1,76 @@
1/* $NetBSD: lsym_rparen_or_rbracket.c,v 1.6 2023/06/16 13:43:30 rillig Exp $ */ 1/* $NetBSD: lsym_rparen_or_rbracket.c,v 1.7 2023/06/16 14:12:10 rillig Exp $ */
2 2
3/* 3/*
4 * Tests for the token lsym_rparen_or_lbracket, which represents ')' or ']', 4 * Tests for the token lsym_rparen_or_lbracket, which represents ')' or ']',
5 * the counterparts for '(' and '['. 5 * the counterparts for '(' and '['.
6 * 6 *
7 * See also: 7 * See also:
8 * lsym_lparen_or_lbracket.c 8 * lsym_lparen_or_lbracket.c
9 */ 9 */
10 10
11//indent input 11//indent input
12int var = (3); 12int var = (3);
13int cast = (int)3; 13int cast = (int)3;
14int cast = (int)(3); 14int cast = (int)(3);
15int call = function(3); 15int call = function(3);
16int array[3] = {1, 2, 3}; 16int array[3] = {1, 2, 3};
17int array[3] = {[2] = 3}; 17int array[3] = {[2] = 3};
18//indent end 18//indent end
19 19
20//indent run-equals-input -di0 20//indent run-equals-input -di0
21 21
22 22
23//indent input 23//indent input
24int a = array[ 24int a = array[
253 253
26]; 26];
27{ 27{
28int a = array[ 28int a = array[
293 293
30]; 30];
31} 31}
32//indent end 32//indent end
33 33
34//indent run -di0 34//indent run -di0
35int a = array[ 35int a = array[
36 3 36 3
37]; 37];
38{ 38{
39 int a = array[ 39 int a = array[
40 3 40 3
41// $ FIXME: Should be one level to the left since it is the outermost bracket. 41// $ FIXME: Should be one level to the left since it is the outermost bracket.
42 ]; 42 ];
43} 43}
44//indent end 44//indent end
45 45
46//indent run -di0 -nlp 46//indent run -di0 -nlp
47int a = array[ 47int a = array[
48 3 48 3
49]; 49];
50{ 50{
51 int a = array[ 51 int a = array[
52 3 52 3
53// $ FIXME: Should be one level to the left since it is the outermost bracket. 53// $ FIXME: Should be one level to the left since it is the outermost bracket.
54 ]; 54 ];
55} 55}
56//indent end 56//indent end
57 57
58 58
59//indent input 59//indent input
60{ 60{
61 dcs_align((u_int)dcs); 61 dcs_align((u_int)dcs);
62 mpools.pools[i] = (memory_pool){NULL, 0, 0}; 62 mpools.pools[i] = (memory_pool){NULL, 0, 0};
63 list_add(l, (const char[3]){'-', (char)c, '\0'}); 63 list_add(l, (const char[3]){'-', (char)c, '\0'});
64} 64}
65//indent end 65//indent end
66 66
67//indent run -ci4 -di0 -nlp 67//indent run -ci4 -di0 -nlp
68{ 68{
69// $ FIXME: No space after cast. 69 dcs_align((u_int)dcs);
70 dcs_align((u_int) dcs); 
71// $ FIXME: Don't add newlines. 70// $ FIXME: Don't add newlines.
72 mpools.pools[i] = (memory_pool) { 71 mpools.pools[i] = (memory_pool) {
73 NULL, 0, 0 72 NULL, 0, 0
74 }; 73 };
75 list_add(l, (const char[3]){'-', (char)c, '\0'}); 74 list_add(l, (const char[3]){'-', (char)c, '\0'});
76} 75}
77//indent end 76//indent end

cvs diff -r1.375 -r1.376 src/usr.bin/indent/indent.c (switch to unified diff)

--- src/usr.bin/indent/indent.c 2023/06/16 12:55:57 1.375
+++ src/usr.bin/indent/indent.c 2023/06/16 14:12:10 1.376
@@ -1,1124 +1,1133 @@ @@ -1,1124 +1,1133 @@
1/* $NetBSD: indent.c,v 1.375 2023/06/16 12:55:57 rillig Exp $ */ 1/* $NetBSD: indent.c,v 1.376 2023/06/16 14:12:10 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.375 2023/06/16 12:55:57 rillig Exp $"); 41__RCSID("$NetBSD: indent.c,v 1.376 2023/06/16 14:12:10 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
52struct options opt = { 52struct 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
73struct parser_state ps; 73struct parser_state ps;
74 74
75struct buffer token; 75struct buffer token;
76 76
77struct buffer lab; 77struct buffer lab;
78struct buffer code; 78struct buffer code;
79struct buffer com; 79struct buffer com;
80 80
81bool found_err; 81bool found_err;
82bool had_eof; 82bool had_eof;
83int line_no = 1; 83int line_no = 1;
84 84
85static struct { 85static struct {
86 struct parser_state *item; 86 struct parser_state *item;
87 size_t len; 87 size_t len;
88 size_t cap; 88 size_t cap;
89} ifdef; 89} ifdef;
90 90
91FILE *input; 91FILE *input;
92FILE *output; 92FILE *output;
93 93
94static const char *in_name = "Standard Input"; 94static const char *in_name = "Standard Input";
95static char backup_name[PATH_MAX]; 95static char backup_name[PATH_MAX];
96static const char *backup_suffix = ".BAK"; 96static const char *backup_suffix = ".BAK";
97 97
98 98
99void * 99void *
100nonnull(void *p) 100nonnull(void *p)
101{ 101{
102 if (p == NULL) 102 if (p == NULL)
103 err(EXIT_FAILURE, NULL); 103 err(EXIT_FAILURE, NULL);
104 return p; 104 return p;
105} 105}
106 106
107static void 107static void
108buf_expand(struct buffer *buf, size_t add_size) 108buf_expand(struct buffer *buf, size_t add_size)
109{ 109{
110 buf->cap = buf->cap + add_size + 400; 110 buf->cap = buf->cap + add_size + 400;
111 buf->s = nonnull(realloc(buf->s, buf->cap)); 111 buf->s = nonnull(realloc(buf->s, buf->cap));
112} 112}
113 113
114#ifdef debug 114#ifdef debug
115void 115void
116buf_terminate(struct buffer *buf) 116buf_terminate(struct buffer *buf)
117{ 117{
118 if (buf->len == buf->cap) 118 if (buf->len == buf->cap)
119 buf_expand(buf, 1); 119 buf_expand(buf, 1);
120 buf->s[buf->len] = '\0'; 120 buf->s[buf->len] = '\0';
121} 121}
122#endif 122#endif
123 123
124void 124void
125buf_add_char(struct buffer *buf, char ch) 125buf_add_char(struct buffer *buf, char ch)
126{ 126{
127 if (buf->len == buf->cap) 127 if (buf->len == buf->cap)
128 buf_expand(buf, 1); 128 buf_expand(buf, 1);
129 buf->s[buf->len++] = ch; 129 buf->s[buf->len++] = ch;
130 buf_terminate(buf); 130 buf_terminate(buf);
131} 131}
132 132
133void 133void
134buf_add_chars(struct buffer *buf, const char *s, size_t len) 134buf_add_chars(struct buffer *buf, const char *s, size_t len)
135{ 135{
136 if (len == 0) 136 if (len == 0)
137 return; 137 return;
138 if (len > buf->cap - buf->len) 138 if (len > buf->cap - buf->len)
139 buf_expand(buf, len); 139 buf_expand(buf, len);
140 memcpy(buf->s + buf->len, s, len); 140 memcpy(buf->s + buf->len, s, len);
141 buf->len += len; 141 buf->len += len;
142 buf_terminate(buf); 142 buf_terminate(buf);
143} 143}
144 144
145static void 145static void
146buf_add_buf(struct buffer *buf, const struct buffer *add) 146buf_add_buf(struct buffer *buf, const struct buffer *add)
147{ 147{
148 buf_add_chars(buf, add->s, add->len); 148 buf_add_chars(buf, add->s, add->len);
149} 149}
150 150
151void 151void
152diag(int level, const char *msg, ...) 152diag(int level, const char *msg, ...)
153{ 153{
154 va_list ap; 154 va_list ap;
155 155
156 if (level != 0) 156 if (level != 0)
157 found_err = true; 157 found_err = true;
158 158
159 va_start(ap, msg); 159 va_start(ap, msg);
160 fprintf(stderr, "%s: %s:%d: ", 160 fprintf(stderr, "%s: %s:%d: ",
161 level == 0 ? "warning" : "error", in_name, line_no); 161 level == 0 ? "warning" : "error", in_name, line_no);
162 vfprintf(stderr, msg, ap); 162 vfprintf(stderr, msg, ap);
163 fprintf(stderr, "\n"); 163 fprintf(stderr, "\n");
164 va_end(ap); 164 va_end(ap);
165} 165}
166 166
167/* 167/*
168 * Compute the indentation from starting at 'ind' and adding the text starting 168 * Compute the indentation from starting at 'ind' and adding the text starting
169 * at 's'. 169 * at 's'.
170 */ 170 */
171int 171int
172ind_add(int ind, const char *s, size_t len) 172ind_add(int ind, const char *s, size_t len)
173{ 173{
174 for (const char *p = s; len > 0; p++, len--) { 174 for (const char *p = s; len > 0; p++, len--) {
175 if (*p == '\n') 175 if (*p == '\n')
176 ind = 0; 176 ind = 0;
177 else if (*p == '\t') 177 else if (*p == '\t')
178 ind = next_tab(ind); 178 ind = next_tab(ind);
179 else if (*p == '\b') 179 else if (*p == '\b')
180 --ind; 180 --ind;
181 else 181 else
182 ++ind; 182 ++ind;
183 } 183 }
184 return ind; 184 return ind;
185} 185}
186 186
187static void 187static void
188init_globals(void) 188init_globals(void)
189{ 189{
190 ps_push(psym_stmt, false); /* as a stop symbol */ 190 ps_push(psym_stmt, false); /* as a stop symbol */
191 ps.prev_lsym = lsym_semicolon; 191 ps.prev_lsym = lsym_semicolon;
192 ps.lbrace_kind = psym_lbrace_block; 192 ps.lbrace_kind = psym_lbrace_block;
193 193
194 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); 194 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX");
195 if (suffix != NULL) 195 if (suffix != NULL)
196 backup_suffix = suffix; 196 backup_suffix = suffix;
197} 197}
198 198
199static void 199static void
200load_profiles(int argc, char **argv) 200load_profiles(int argc, char **argv)
201{ 201{
202 const char *profile_name = NULL; 202 const char *profile_name = NULL;
203 203
204 for (int i = 1; i < argc; ++i) { 204 for (int i = 1; i < argc; ++i) {
205 const char *arg = argv[i]; 205 const char *arg = argv[i];
206 206
207 if (strcmp(arg, "-npro") == 0) 207 if (strcmp(arg, "-npro") == 0)
208 return; 208 return;
209 if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0') 209 if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0')
210 profile_name = arg + 2; 210 profile_name = arg + 2;
211 } 211 }
212 212
213 load_profile_files(profile_name); 213 load_profile_files(profile_name);
214} 214}
215 215
216/* 216/*
217 * Copy the input file to the backup file, then make the backup file the input 217 * Copy the input file to the backup file, then make the backup file the input
218 * and the original input file the output. 218 * and the original input file the output.
219 */ 219 */
220static void 220static void
221copy_to_bak_file(void) 221copy_to_bak_file(void)
222{ 222{
223 size_t n; 223 size_t n;
224 char buff[BUFSIZ]; 224 char buff[BUFSIZ];
225 225
226 const char *last_slash = strrchr(in_name, '/'); 226 const char *last_slash = strrchr(in_name, '/');
227 const char *base = last_slash != NULL ? last_slash + 1 : in_name; 227 const char *base = last_slash != NULL ? last_slash + 1 : in_name;
228 snprintf(backup_name, sizeof(backup_name), "%s%s", base, backup_suffix); 228 snprintf(backup_name, sizeof(backup_name), "%s%s", base, backup_suffix);
229 229
230 /* copy the input file to the backup file */ 230 /* copy the input file to the backup file */
231 FILE *bak = fopen(backup_name, "w"); 231 FILE *bak = fopen(backup_name, "w");
232 if (bak == NULL) 232 if (bak == NULL)
233 err(1, "%s", backup_name); 233 err(1, "%s", backup_name);
234 234
235 while ((n = fread(buff, 1, sizeof(buff), input)) > 0) 235 while ((n = fread(buff, 1, sizeof(buff), input)) > 0)
236 if (fwrite(buff, 1, n, bak) != n) 236 if (fwrite(buff, 1, n, bak) != n)
237 err(1, "%s", backup_name); 237 err(1, "%s", backup_name);
238 if (fclose(input) != 0) 238 if (fclose(input) != 0)
239 err(1, "%s", in_name); 239 err(1, "%s", in_name);
240 if (fclose(bak) != 0) 240 if (fclose(bak) != 0)
241 err(1, "%s", backup_name); 241 err(1, "%s", backup_name);
242 242
243 /* re-open the backup file as the input file */ 243 /* re-open the backup file as the input file */
244 input = fopen(backup_name, "r"); 244 input = fopen(backup_name, "r");
245 if (input == NULL) 245 if (input == NULL)
246 err(1, "%s", backup_name); 246 err(1, "%s", backup_name);
247 /* now the original input file will be the output */ 247 /* now the original input file will be the output */
248 output = fopen(in_name, "w"); 248 output = fopen(in_name, "w");
249 if (output == NULL) { 249 if (output == NULL) {
250 remove(backup_name); 250 remove(backup_name);
251 err(1, "%s", in_name); 251 err(1, "%s", in_name);
252 } 252 }
253} 253}
254 254
255static void 255static void
256parse_command_line(int argc, char **argv) 256parse_command_line(int argc, char **argv)
257{ 257{
258 for (int i = 1; i < argc; ++i) { 258 for (int i = 1; i < argc; ++i) {
259 const char *arg = argv[i]; 259 const char *arg = argv[i];
260 260
261 if (arg[0] == '-') { 261 if (arg[0] == '-') {
262 set_option(arg, "Command line"); 262 set_option(arg, "Command line");
263 263
264 } else if (input == NULL) { 264 } else if (input == NULL) {
265 in_name = arg; 265 in_name = arg;
266 if ((input = fopen(in_name, "r")) == NULL) 266 if ((input = fopen(in_name, "r")) == NULL)
267 err(1, "%s", in_name); 267 err(1, "%s", in_name);
268 268
269 } else if (output == NULL) { 269 } else if (output == NULL) {
270 if (strcmp(arg, in_name) == 0) 270 if (strcmp(arg, in_name) == 0)
271 errx(1, "input and output files " 271 errx(1, "input and output files "
272 "must be different"); 272 "must be different");
273 if ((output = fopen(arg, "w")) == NULL) 273 if ((output = fopen(arg, "w")) == NULL)
274 err(1, "%s", arg); 274 err(1, "%s", arg);
275 275
276 } else 276 } else
277 errx(1, "too many arguments: %s", arg); 277 errx(1, "too many arguments: %s", arg);
278 } 278 }
279 279
280 if (input == NULL) { 280 if (input == NULL) {
281 input = stdin; 281 input = stdin;
282 output = stdout; 282 output = stdout;
283 } else if (output == NULL) 283 } else if (output == NULL)
284 copy_to_bak_file(); 284 copy_to_bak_file();
285 285
286 if (opt.comment_column <= 1) 286 if (opt.comment_column <= 1)
287 opt.comment_column = 2; /* don't put normal comments in column 287 opt.comment_column = 2; /* don't put normal comments in column
288 * 1, see opt.format_col1_comments */ 288 * 1, see opt.format_col1_comments */
289 if (opt.block_comment_max_line_length <= 0) 289 if (opt.block_comment_max_line_length <= 0)
290 opt.block_comment_max_line_length = opt.max_line_length; 290 opt.block_comment_max_line_length = opt.max_line_length;
291 if (opt.local_decl_indent < 0) 291 if (opt.local_decl_indent < 0)
292 opt.local_decl_indent = opt.decl_indent; 292 opt.local_decl_indent = opt.decl_indent;
293 if (opt.decl_comment_column <= 0) 293 if (opt.decl_comment_column <= 0)
294 opt.decl_comment_column = opt.left_justify_decl 294 opt.decl_comment_column = opt.left_justify_decl
295 ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) 295 ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8)
296 : opt.comment_column; 296 : opt.comment_column;
297 if (opt.continuation_indent == 0) 297 if (opt.continuation_indent == 0)
298 opt.continuation_indent = opt.indent_size; 298 opt.continuation_indent = opt.indent_size;
299} 299}
300 300
301static void 301static void
302set_initial_indentation(void) 302set_initial_indentation(void)
303{ 303{
304 inp_read_line(); 304 inp_read_line();
305 305
306 int ind = 0; 306 int ind = 0;
307 for (const char *p = inp_p;; p++) { 307 for (const char *p = inp_p;; p++) {
308 if (*p == ' ') 308 if (*p == ' ')
309 ind++; 309 ind++;
310 else if (*p == '\t') 310 else if (*p == '\t')
311 ind = next_tab(ind); 311 ind = next_tab(ind);
312 else 312 else
313 break; 313 break;
314 } 314 }
315 315
316 ps.ind_level = ps.ind_level_follow = ind / opt.indent_size; 316 ps.ind_level = ps.ind_level_follow = ind / opt.indent_size;
317} 317}
318 318
319static bool 319static bool
320should_break_line(lexer_symbol lsym) 320should_break_line(lexer_symbol lsym)
321{ 321{
322 if (lsym == lsym_semicolon) 322 if (lsym == lsym_semicolon)
323 return false; 323 return false;
324 if (ps.prev_lsym == lsym_lbrace || ps.prev_lsym == lsym_semicolon) 324 if (ps.prev_lsym == lsym_lbrace || ps.prev_lsym == lsym_semicolon)
325 return true; 325 return true;
326 if (lsym == lsym_lbrace && opt.brace_same_line) 326 if (lsym == lsym_lbrace && opt.brace_same_line)
327 return false; 327 return false;
328 return true; 328 return true;
329} 329}
330 330
331static void 331static void
332move_com_to_code(lexer_symbol lsym) 332move_com_to_code(lexer_symbol lsym)
333{ 333{
334 if (ps.want_blank) 334 if (ps.want_blank)
335 buf_add_char(&code, ' '); 335 buf_add_char(&code, ' ');
336 buf_add_buf(&code, &com); 336 buf_add_buf(&code, &com);
337 buf_clear(&com); 337 buf_clear(&com);
338 ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; 338 ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket;
339} 339}
340 340
341static void 341static void
342update_ps_lbrace_kind(lexer_symbol lsym) 342update_ps_lbrace_kind(lexer_symbol lsym)
343{ 343{
344 if (lsym == lsym_tag) { 344 if (lsym == lsym_tag) {
345 ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : 345 ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct :
346 token.s[0] == 'u' ? psym_lbrace_union : 346 token.s[0] == 'u' ? psym_lbrace_union :
347 psym_lbrace_enum; 347 psym_lbrace_enum;
348 } else if (lsym == lsym_type_outside_parentheses 348 } else if (lsym == lsym_type_outside_parentheses
349 || lsym == lsym_word 349 || lsym == lsym_word
350 || lsym == lsym_lbrace) { 350 || lsym == lsym_lbrace) {
351 /* Keep the current '{' kind. */ 351 /* Keep the current '{' kind. */
352 } else 352 } else
353 ps.lbrace_kind = psym_lbrace_block; 353 ps.lbrace_kind = psym_lbrace_block;
354} 354}
355 355
356static void 356static void
357indent_declarator(int decl_ind, bool tabs_to_var) 357indent_declarator(int decl_ind, bool tabs_to_var)
358{ 358{
359 int base = ps.ind_level * opt.indent_size; 359 int base = ps.ind_level * opt.indent_size;
360 int ind = ind_add(base, code.s, code.len); 360 int ind = ind_add(base, code.s, code.len);
361 int target = base + decl_ind; 361 int target = base + decl_ind;
362 size_t orig_code_len = code.len; 362 size_t orig_code_len = code.len;
363 363
364 if (tabs_to_var) 364 if (tabs_to_var)
365 for (int next; (next = next_tab(ind)) <= target; ind = next) 365 for (int next; (next = next_tab(ind)) <= target; ind = next)
366 buf_add_char(&code, '\t'); 366 buf_add_char(&code, '\t');
367 for (; ind < target; ind++) 367 for (; ind < target; ind++)
368 buf_add_char(&code, ' '); 368 buf_add_char(&code, ' ');
369 if (code.len == orig_code_len && ps.want_blank) 369 if (code.len == orig_code_len && ps.want_blank)
370 buf_add_char(&code, ' '); 370 buf_add_char(&code, ' ');
371 371
372 ps.want_blank = false; 372 ps.want_blank = false;
373 ps.decl_indent_done = true; 373 ps.decl_indent_done = true;
374} 374}
375 375
376static bool 376static bool
377is_function_pointer_declaration(void) 377is_function_pointer_declaration(void)
378{ 378{
379 return ps.in_decl 379 return ps.in_decl
380 && !ps.in_typedef_decl 380 && !ps.in_typedef_decl
381 && !ps.in_init 381 && !ps.in_init
382 && !ps.decl_indent_done 382 && !ps.decl_indent_done
383 && !ps.line_has_func_def 383 && !ps.line_has_func_def
384 && ps.ind_paren_level == 0; 384 && ps.ind_paren_level == 0;
385} 385}
386 386
387static int 387static int
388process_eof(void) 388process_eof(void)
389{ 389{
390 finish_output(); 390 finish_output();
391 391
392 if (ps.psyms.len > 2) /* check for balanced braces */ 392 if (ps.psyms.len > 2) /* check for balanced braces */
393 diag(1, "Stuff missing from end of file"); 393 diag(1, "Stuff missing from end of file");
394 394
395 return found_err ? EXIT_FAILURE : EXIT_SUCCESS; 395 return found_err ? EXIT_FAILURE : EXIT_SUCCESS;
396} 396}
397 397
398/* move the whole line to the 'label' buffer */ 398/* move the whole line to the 'label' buffer */
399static void 399static void
400read_preprocessing_line(void) 400read_preprocessing_line(void)
401{ 401{
402 enum { 402 enum {
403 PLAIN, STR, CHR, COMM 403 PLAIN, STR, CHR, COMM
404 } state = PLAIN; 404 } state = PLAIN;
405 405
406 buf_add_char(&lab, '#'); 406 buf_add_char(&lab, '#');
407 407
408 while (inp_p[0] != '\n' || (state == COMM && !had_eof)) { 408 while (inp_p[0] != '\n' || (state == COMM && !had_eof)) {
409 buf_add_char(&lab, inp_next()); 409 buf_add_char(&lab, inp_next());
410 switch (lab.s[lab.len - 1]) { 410 switch (lab.s[lab.len - 1]) {
411 case '\\': 411 case '\\':
412 if (state != COMM) 412 if (state != COMM)
413 buf_add_char(&lab, inp_next()); 413 buf_add_char(&lab, inp_next());
414 break; 414 break;
415 case '/': 415 case '/':
416 if (inp_p[0] == '*' && state == PLAIN) { 416 if (inp_p[0] == '*' && state == PLAIN) {
417 state = COMM; 417 state = COMM;
418 buf_add_char(&lab, *inp_p++); 418 buf_add_char(&lab, *inp_p++);
419 } 419 }
420 break; 420 break;
421 case '"': 421 case '"':
422 if (state == STR) 422 if (state == STR)
423 state = PLAIN; 423 state = PLAIN;
424 else if (state == PLAIN) 424 else if (state == PLAIN)
425 state = STR; 425 state = STR;
426 break; 426 break;
427 case '\'': 427 case '\'':
428 if (state == CHR) 428 if (state == CHR)
429 state = PLAIN; 429 state = PLAIN;
430 else if (state == PLAIN) 430 else if (state == PLAIN)
431 state = CHR; 431 state = CHR;
432 break; 432 break;
433 case '*': 433 case '*':
434 if (inp_p[0] == '/' && state == COMM) { 434 if (inp_p[0] == '/' && state == COMM) {
435 state = PLAIN; 435 state = PLAIN;
436 buf_add_char(&lab, *inp_p++); 436 buf_add_char(&lab, *inp_p++);
437 } 437 }
438 break; 438 break;
439 } 439 }
440 } 440 }
441 441
442 while (lab.len > 0 && ch_isblank(lab.s[lab.len - 1])) 442 while (lab.len > 0 && ch_isblank(lab.s[lab.len - 1]))
443 lab.len--; 443 lab.len--;
444 buf_terminate(&lab); 444 buf_terminate(&lab);
445} 445}
446 446
447static void 447static void
448paren_stack_push(struct paren_stack *s, int indent, enum paren_level_cast cast) 448paren_stack_push(struct paren_stack *s, int indent, enum paren_level_cast cast)
449{ 449{
450 if (s->len == s->cap) { 450 if (s->len == s->cap) {
451 s->cap = 10 + s->cap; 451 s->cap = 10 + s->cap;
452 s->item = nonnull(realloc(s->item, 452 s->item = nonnull(realloc(s->item,
453 sizeof(s->item[0]) * s->cap)); 453 sizeof(s->item[0]) * s->cap));
454 } 454 }
455 s->item[s->len++] = (struct paren_level){indent, cast}; 455 s->item[s->len++] = (struct paren_level){indent, cast};
456} 456}
457 457
458static void * 458static void *
459dup_mem(const void *src, size_t size) 459dup_mem(const void *src, size_t size)
460{ 460{
461 return memcpy(nonnull(malloc(size)), src, size); 461 return memcpy(nonnull(malloc(size)), src, size);
462} 462}
463 463
464#define dup_array(src, len) \ 464#define dup_array(src, len) \
465 dup_mem((src), sizeof((src)[0]) * (len)) 465 dup_mem((src), sizeof((src)[0]) * (len))
466#define copy_array(dst, src, len) \ 466#define copy_array(dst, src, len) \
467 memcpy((dst), (src), sizeof((dst)[0]) * (len)) 467 memcpy((dst), (src), sizeof((dst)[0]) * (len))
468 468
469static void 469static void
470parser_state_back_up(struct parser_state *dst) 470parser_state_back_up(struct parser_state *dst)
471{ 471{
472 *dst = ps; 472 *dst = ps;
473 473
474 dst->paren.item = dup_array(ps.paren.item, ps.paren.len); 474 dst->paren.item = dup_array(ps.paren.item, ps.paren.len);
475 dst->psyms.sym = dup_array(ps.psyms.sym, ps.psyms.len); 475 dst->psyms.sym = dup_array(ps.psyms.sym, ps.psyms.len);
476 dst->psyms.ind_level = dup_array(ps.psyms.ind_level, ps.psyms.len); 476 dst->psyms.ind_level = dup_array(ps.psyms.ind_level, ps.psyms.len);
477} 477}
478 478
479static void 479static void
480parser_state_restore(const struct parser_state *src) 480parser_state_restore(const struct parser_state *src)
481{ 481{
482 struct paren_level *ps_paren_item = ps.paren.item; 482 struct paren_level *ps_paren_item = ps.paren.item;
483 size_t ps_paren_cap = ps.paren.cap; 483 size_t ps_paren_cap = ps.paren.cap;
484 enum parser_symbol *ps_psyms_sym = ps.psyms.sym; 484 enum parser_symbol *ps_psyms_sym = ps.psyms.sym;
485 int *ps_psyms_ind_level = ps.psyms.ind_level; 485 int *ps_psyms_ind_level = ps.psyms.ind_level;
486 size_t ps_psyms_cap = ps.psyms.cap; 486 size_t ps_psyms_cap = ps.psyms.cap;
487 487
488 ps = *src; 488 ps = *src;
489 489
490 ps.paren.item = ps_paren_item; 490 ps.paren.item = ps_paren_item;
491 ps.paren.cap = ps_paren_cap; 491 ps.paren.cap = ps_paren_cap;
492 ps.psyms.sym = ps_psyms_sym; 492 ps.psyms.sym = ps_psyms_sym;
493 ps.psyms.ind_level = ps_psyms_ind_level; 493 ps.psyms.ind_level = ps_psyms_ind_level;
494 ps.psyms.cap = ps_psyms_cap; 494 ps.psyms.cap = ps_psyms_cap;
495 495
496 copy_array(ps.paren.item, src->paren.item, src->paren.len); 496 copy_array(ps.paren.item, src->paren.item, src->paren.len);
497 copy_array(ps.psyms.sym, src->psyms.sym, src->psyms.len); 497 copy_array(ps.psyms.sym, src->psyms.sym, src->psyms.len);
498 copy_array(ps.psyms.ind_level, src->psyms.ind_level, src->psyms.len); 498 copy_array(ps.psyms.ind_level, src->psyms.ind_level, src->psyms.len);
499} 499}
500 500
501static void 501static void
502parser_state_free(struct parser_state *pst) 502parser_state_free(struct parser_state *pst)
503{ 503{
504 free(pst->paren.item); 504 free(pst->paren.item);
505 free(pst->psyms.sym); 505 free(pst->psyms.sym);
506 free(pst->psyms.ind_level); 506 free(pst->psyms.ind_level);
507} 507}
508 508
509static void 509static void
510process_preprocessing(void) 510process_preprocessing(void)
511{ 511{
512 if (lab.len > 0 || code.len > 0 || com.len > 0) 512 if (lab.len > 0 || code.len > 0 || com.len > 0)
513 output_line(); 513 output_line();
514 514
515 read_preprocessing_line(); 515 read_preprocessing_line();
516 516
517 const char *dir = lab.s + 1, *line_end = lab.s + lab.len; 517 const char *dir = lab.s + 1, *line_end = lab.s + lab.len;
518 while (dir < line_end && ch_isblank(*dir)) 518 while (dir < line_end && ch_isblank(*dir))
519 dir++; 519 dir++;
520 size_t dir_len = 0; 520 size_t dir_len = 0;
521 while (dir + dir_len < line_end && ch_isalpha(dir[dir_len])) 521 while (dir + dir_len < line_end && ch_isalpha(dir[dir_len]))
522 dir_len++; 522 dir_len++;
523 523
524 if (dir_len >= 2 && memcmp(dir, "if", 2) == 0) { 524 if (dir_len >= 2 && memcmp(dir, "if", 2) == 0) {
525 if (ifdef.len >= ifdef.cap) { 525 if (ifdef.len >= ifdef.cap) {
526 ifdef.cap += 5; 526 ifdef.cap += 5;
527 ifdef.item = nonnull(realloc(ifdef.item, 527 ifdef.item = nonnull(realloc(ifdef.item,
528 sizeof(ifdef.item[0]) * ifdef.cap)); 528 sizeof(ifdef.item[0]) * ifdef.cap));
529 } 529 }
530 parser_state_back_up(ifdef.item + ifdef.len++); 530 parser_state_back_up(ifdef.item + ifdef.len++);
531 out.line_kind = lk_pre_if; 531 out.line_kind = lk_pre_if;
532 532
533 } else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) { 533 } else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) {
534 if (ifdef.len == 0) 534 if (ifdef.len == 0)
535 diag(1, "Unmatched #%.*s", (int)dir_len, dir); 535 diag(1, "Unmatched #%.*s", (int)dir_len, dir);
536 else 536 else
537 parser_state_restore(ifdef.item + ifdef.len - 1); 537 parser_state_restore(ifdef.item + ifdef.len - 1);
538 out.line_kind = lk_pre_other; 538 out.line_kind = lk_pre_other;
539 539
540 } else if (dir_len == 5 && memcmp(dir, "endif", 5) == 0) { 540 } else if (dir_len == 5 && memcmp(dir, "endif", 5) == 0) {
541 if (ifdef.len == 0) 541 if (ifdef.len == 0)
542 diag(1, "Unmatched #endif"); 542 diag(1, "Unmatched #endif");
543 else 543 else
544 parser_state_free(ifdef.item + --ifdef.len); 544 parser_state_free(ifdef.item + --ifdef.len);
545 out.line_kind = lk_pre_endif; 545 out.line_kind = lk_pre_endif;
546 } else 546 } else
547 out.line_kind = lk_pre_other; 547 out.line_kind = lk_pre_other;
548} 548}
549 549
550static void 550static void
551process_newline(void) 551process_newline(void)
552{ 552{
553 if (ps.prev_lsym == lsym_comma 553 if (ps.prev_lsym == lsym_comma
554 && ps.paren.len == 0 && !ps.in_init 554 && ps.paren.len == 0 && !ps.in_init
555 && !opt.break_after_comma && ps.break_after_comma 555 && !opt.break_after_comma && ps.break_after_comma
556 && lab.len == 0 /* for preprocessing lines */ 556 && lab.len == 0 /* for preprocessing lines */
557 && com.len == 0) 557 && com.len == 0)
558 goto stay_in_line; 558 goto stay_in_line;
559 if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr 559 if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr
560 && opt.brace_same_line 560 && opt.brace_same_line
561 && com.len == 0) { 561 && com.len == 0) {
562 ps.want_newline = true; 562 ps.want_newline = true;
563 goto stay_in_line; 563 goto stay_in_line;
564 } 564 }
565 565
566 output_line(); 566 output_line();
567 567
568stay_in_line: 568stay_in_line:
569 ++line_no; 569 ++line_no;
570} 570}
571 571
572static bool 572static bool
573want_blank_before_lparen(void) 573want_blank_before_lparen(void)
574{ 574{
575 if (opt.proc_calls_space) 575 if (opt.proc_calls_space)
576 return true; 576 return true;
577 if (ps.prev_lsym == lsym_rparen || ps.prev_lsym == lsym_rbracket) 577 if (ps.prev_lsym == lsym_rparen || ps.prev_lsym == lsym_rbracket)
578 return false; 578 return false;
579 if (ps.prev_lsym == lsym_offsetof) 579 if (ps.prev_lsym == lsym_offsetof)
580 return false; 580 return false;
581 if (ps.prev_lsym == lsym_sizeof) 581 if (ps.prev_lsym == lsym_sizeof)
582 return opt.blank_after_sizeof; 582 return opt.blank_after_sizeof;
583 if (ps.prev_lsym == lsym_word || ps.prev_lsym == lsym_funcname) 583 if (ps.prev_lsym == lsym_word || ps.prev_lsym == lsym_funcname)
584 return false; 584 return false;
585 return true; 585 return true;
586} 586}
587 587
588static void 588static void
589process_lparen(void) 589process_lparen(void)
590{ 590{
591 591
592 if (is_function_pointer_declaration()) 592 if (is_function_pointer_declaration())
593 indent_declarator(ps.decl_ind, ps.tabs_to_var); 593 indent_declarator(ps.decl_ind, ps.tabs_to_var);
594 else if (ps.want_blank && want_blank_before_lparen()) 594 else if (ps.want_blank && want_blank_before_lparen())
595 buf_add_char(&code, ' '); 595 buf_add_char(&code, ' ');
596 ps.want_blank = false; 596 ps.want_blank = false;
597 buf_add_buf(&code, &token); 597 buf_add_buf(&code, &token);
598 598
599 if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) 599 if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0)
600 ps.extra_expr_indent = eei_maybe; 600 ps.extra_expr_indent = eei_maybe;
601 601
602 if (ps.in_var_decl && ps.psyms.len <= 3 && !ps.in_init) { 602 if (ps.in_var_decl && ps.psyms.len <= 3 && !ps.in_init) {
603 parse(psym_stmt); /* prepare for function definition */ 603 parse(psym_stmt); /* prepare for function definition */
604 ps.in_var_decl = false; 604 ps.in_var_decl = false;
605 } 605 }
606 606
607 enum paren_level_cast cast = cast_unknown; 607 enum paren_level_cast cast = cast_unknown;
608 if (ps.prev_lsym == lsym_offsetof 608 if (ps.prev_lsym == lsym_offsetof
609 || ps.prev_lsym == lsym_sizeof 609 || ps.prev_lsym == lsym_sizeof
610 || ps.prev_lsym == lsym_for 610 || ps.prev_lsym == lsym_for
611 || ps.prev_lsym == lsym_if 611 || ps.prev_lsym == lsym_if
612 || ps.prev_lsym == lsym_switch 612 || ps.prev_lsym == lsym_switch
613 || ps.prev_lsym == lsym_while 613 || ps.prev_lsym == lsym_while
614 || ps.line_has_func_def) 614 || ps.line_has_func_def)
615 cast = cast_no; 615 cast = cast_no;
616 616
617 paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast); 617 paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast);
618} 618}
619 619
 620static bool
 621rparen_is_cast(bool paren_cast)
 622{
 623 if (ps.in_func_def_params)
 624 return false;
 625 if (ps.prev_lsym == lsym_unary_op)
 626 return true;
 627 if (ps.line_has_decl && !ps.in_init)
 628 return false;
 629 return paren_cast || ch_isalpha(inp_p[0]);
 630}
 631
620static void 632static void
621process_rparen(void) 633process_rparen(void)
622{ 634{
623 if (ps.paren.len == 0) 635 if (ps.paren.len == 0)
624 diag(0, "Extra '%c'", *token.s); 636 diag(0, "Extra '%c'", *token.s);
625 637
626 ps.prev_paren_was_cast = ps.paren.len > 0 638 bool paren_cast = ps.paren.len > 0
627 && ps.paren.item[--ps.paren.len].cast == cast_maybe 639 && ps.paren.item[--ps.paren.len].cast == cast_maybe;
628 && !ps.in_func_def_params 640 ps.prev_paren_was_cast = rparen_is_cast(paren_cast);
629 && !(ps.line_has_decl && !ps.in_init); 
630 if (ps.prev_lsym == lsym_unary_op) 
631 ps.prev_paren_was_cast = true; 
632 if (ps.prev_paren_was_cast) { 641 if (ps.prev_paren_was_cast) {
633 ps.next_unary = true; 642 ps.next_unary = true;
634 ps.want_blank = opt.space_after_cast; 643 ps.want_blank = opt.space_after_cast;
635 } else 644 } else
636 ps.want_blank = true; 645 ps.want_blank = true;
637 646
638 if (code.len == 0) 647 if (code.len == 0)
639 ps.ind_paren_level = (int)ps.paren.len; 648 ps.ind_paren_level = (int)ps.paren.len;
640 649
641 buf_add_buf(&code, &token); 650 buf_add_buf(&code, &token);
642 651
643 if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { 652 if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) {
644 parse(ps.spaced_expr_psym); 653 parse(ps.spaced_expr_psym);
645 ps.spaced_expr_psym = psym_0; 654 ps.spaced_expr_psym = psym_0;
646 655
647 ps.want_newline = true; 656 ps.want_newline = true;
648 ps.next_unary = true; 657 ps.next_unary = true;
649 ps.in_stmt_or_decl = false; 658 ps.in_stmt_or_decl = false;
650 ps.want_blank = true; 659 ps.want_blank = true;
651 out.line_kind = lk_stmt_head; 660 out.line_kind = lk_stmt_head;
652 if (ps.extra_expr_indent == eei_maybe) 661 if (ps.extra_expr_indent == eei_maybe)
653 ps.extra_expr_indent = eei_last; 662 ps.extra_expr_indent = eei_last;
654 } 663 }
655} 664}
656 665
657static void 666static void
658process_lbracket(void) 667process_lbracket(void)
659{ 668{
660 if (code.len > 0 669 if (code.len > 0
661 && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) 670 && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op))
662 buf_add_char(&code, ' '); 671 buf_add_char(&code, ' ');
663 buf_add_buf(&code, &token); 672 buf_add_buf(&code, &token);
664 ps.want_blank = false; 673 ps.want_blank = false;
665 674
666 paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast_no); 675 paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast_no);
667} 676}
668 677
669static void 678static void
670process_rbracket(void) 679process_rbracket(void)
671{ 680{
672 if (ps.paren.len == 0) 681 if (ps.paren.len == 0)
673 diag(0, "Extra '%c'", *token.s); 682 diag(0, "Extra '%c'", *token.s);
674 if (ps.paren.len > 0) 683 if (ps.paren.len > 0)
675 ps.paren.len--; 684 ps.paren.len--;
676 685
677 if (code.len == 0) 686 if (code.len == 0)
678 ps.ind_paren_level = (int)ps.paren.len; 687 ps.ind_paren_level = (int)ps.paren.len;
679 688
680 buf_add_buf(&code, &token); 689 buf_add_buf(&code, &token);
681 ps.want_blank = true; 690 ps.want_blank = true;
682} 691}
683 692
684static void 693static void
685process_lbrace(void) 694process_lbrace(void)
686{ 695{
687 if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { 696 if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) {
688 ps.in_var_decl = true; // XXX: not really 697 ps.in_var_decl = true; // XXX: not really
689 ps.in_init = true; 698 ps.in_init = true;
690 } 699 }
691 700
692 if (out.line_kind == lk_stmt_head) 701 if (out.line_kind == lk_stmt_head)
693 out.line_kind = lk_other; 702 out.line_kind = lk_other;
694 703
695 ps.in_stmt_or_decl = false; /* don't indent the {} */ 704 ps.in_stmt_or_decl = false; /* don't indent the {} */
696 705
697 if (ps.in_init) 706 if (ps.in_init)
698 ps.init_level++; 707 ps.init_level++;
699 else 708 else
700 ps.want_newline = true; 709 ps.want_newline = true;
701 710
702 if (code.len > 0 && !ps.in_init) { 711 if (code.len > 0 && !ps.in_init) {
703 if (!opt.brace_same_line || 712 if (!opt.brace_same_line ||
704 (code.len > 0 && code.s[code.len - 1] == '}')) 713 (code.len > 0 && code.s[code.len - 1] == '}'))
705 output_line(); 714 output_line();
706 else if (ps.in_func_def_params && !ps.in_var_decl) { 715 else if (ps.in_func_def_params && !ps.in_var_decl) {
707 ps.ind_level_follow = 0; 716 ps.ind_level_follow = 0;
708 if (opt.function_brace_split) 717 if (opt.function_brace_split)
709 output_line(); 718 output_line();
710 else 719 else
711 ps.want_blank = true; 720 ps.want_blank = true;
712 } 721 }
713 } 722 }
714 723
715 if (ps.paren.len > 0 && ps.init_level == 0) { 724 if (ps.paren.len > 0 && ps.init_level == 0) {
716 diag(1, "Unbalanced parentheses"); 725 diag(1, "Unbalanced parentheses");
717 ps.paren.len = 0; 726 ps.paren.len = 0;
718 if (ps.spaced_expr_psym != psym_0) { 727 if (ps.spaced_expr_psym != psym_0) {
719 parse(ps.spaced_expr_psym); 728 parse(ps.spaced_expr_psym);
720 ps.spaced_expr_psym = psym_0; 729 ps.spaced_expr_psym = psym_0;
721 ps.ind_level = ps.ind_level_follow; 730 ps.ind_level = ps.ind_level_follow;
722 } 731 }
723 } 732 }
724 733
725 if (code.len == 0) 734 if (code.len == 0)
726 ps.line_is_stmt_cont = false; 735 ps.line_is_stmt_cont = false;
727 if (ps.in_decl && ps.in_var_decl) { 736 if (ps.in_decl && ps.in_var_decl) {
728 ps.di_stack[ps.decl_level] = ps.decl_ind; 737 ps.di_stack[ps.decl_level] = ps.decl_ind;
729 if (++ps.decl_level == (int)array_length(ps.di_stack)) { 738 if (++ps.decl_level == (int)array_length(ps.di_stack)) {
730 diag(0, "Reached internal limit of %zu struct levels", 739 diag(0, "Reached internal limit of %zu struct levels",
731 array_length(ps.di_stack)); 740 array_length(ps.di_stack));
732 ps.decl_level--; 741 ps.decl_level--;
733 } 742 }
734 } else { 743 } else {
735 ps.line_has_decl = false; /* don't do special indentation 744 ps.line_has_decl = false; /* don't do special indentation
736 * of comments */ 745 * of comments */
737 ps.in_func_def_params = false; 746 ps.in_func_def_params = false;
738 ps.in_decl = false; 747 ps.in_decl = false;
739 } 748 }
740 749
741 ps.decl_ind = 0; 750 ps.decl_ind = 0;
742 parse(ps.lbrace_kind); 751 parse(ps.lbrace_kind);
743 if (ps.want_blank) 752 if (ps.want_blank)
744 buf_add_char(&code, ' '); 753 buf_add_char(&code, ' ');
745 ps.want_blank = false; 754 ps.want_blank = false;
746 buf_add_char(&code, '{'); 755 buf_add_char(&code, '{');
747 ps.declaration = decl_no; 756 ps.declaration = decl_no;
748} 757}
749 758
750static void 759static void
751process_rbrace(void) 760process_rbrace(void)
752{ 761{
753 if (ps.paren.len > 0 && ps.init_level == 0) { 762 if (ps.paren.len > 0 && ps.init_level == 0) {
754 diag(1, "Unbalanced parentheses"); 763 diag(1, "Unbalanced parentheses");
755 ps.paren.len = 0; 764 ps.paren.len = 0;
756 ps.spaced_expr_psym = psym_0; 765 ps.spaced_expr_psym = psym_0;
757 } 766 }
758 767
759 ps.declaration = decl_no; 768 ps.declaration = decl_no;
760 if (ps.init_level > 0) 769 if (ps.init_level > 0)
761 ps.init_level--; 770 ps.init_level--;
762 771
763 if (code.len > 0 && !ps.in_init) 772 if (code.len > 0 && !ps.in_init)
764 output_line(); 773 output_line();
765 774
766 buf_add_char(&code, '}'); 775 buf_add_char(&code, '}');
767 ps.want_blank = true; 776 ps.want_blank = true;
768 ps.in_stmt_or_decl = false; // XXX: Initializers don't end a stmt 777 ps.in_stmt_or_decl = false; // XXX: Initializers don't end a stmt
769 ps.line_is_stmt_cont = false; 778 ps.line_is_stmt_cont = false;
770 779
771 if (ps.decl_level > 0) { /* multi-level structure declaration */ 780 if (ps.decl_level > 0) { /* multi-level structure declaration */
772 ps.decl_ind = ps.di_stack[--ps.decl_level]; 781 ps.decl_ind = ps.di_stack[--ps.decl_level];
773 if (ps.decl_level == 0 && !ps.in_func_def_params) { 782 if (ps.decl_level == 0 && !ps.in_func_def_params) {
774 ps.declaration = decl_begin; 783 ps.declaration = decl_begin;
775 ps.decl_ind = ps.ind_level == 0 784 ps.decl_ind = ps.ind_level == 0
776 ? opt.decl_indent : opt.local_decl_indent; 785 ? opt.decl_indent : opt.local_decl_indent;
777 } 786 }
778 ps.in_decl = true; 787 ps.in_decl = true;
779 } 788 }
780 789
781 if (ps.psyms.len == 3) 790 if (ps.psyms.len == 3)
782 out.line_kind = lk_func_end; 791 out.line_kind = lk_func_end;
783 792
784 parse(psym_rbrace); 793 parse(psym_rbrace);
785 794
786 if (!ps.in_var_decl 795 if (!ps.in_var_decl
787 && ps.psyms.sym[ps.psyms.len - 1] != psym_do_stmt 796 && ps.psyms.sym[ps.psyms.len - 1] != psym_do_stmt
788 && ps.psyms.sym[ps.psyms.len - 1] != psym_if_expr_stmt) 797 && ps.psyms.sym[ps.psyms.len - 1] != psym_if_expr_stmt)
789 ps.want_newline = true; 798 ps.want_newline = true;
790} 799}
791 800
792static void 801static void
793process_period(void) 802process_period(void)
794{ 803{
795 if (code.len > 0 && code.s[code.len - 1] == ',') 804 if (code.len > 0 && code.s[code.len - 1] == ',')
796 buf_add_char(&code, ' '); 805 buf_add_char(&code, ' ');
797 buf_add_char(&code, '.'); 806 buf_add_char(&code, '.');
798 ps.want_blank = false; 807 ps.want_blank = false;
799} 808}
800 809
801static void 810static void
802process_unary_op(void) 811process_unary_op(void)
803{ 812{
804 if (is_function_pointer_declaration()) { 813 if (is_function_pointer_declaration()) {
805 int ind = ps.decl_ind - (int)token.len; 814 int ind = ps.decl_ind - (int)token.len;
806 indent_declarator(ind, ps.tabs_to_var); 815 indent_declarator(ind, ps.tabs_to_var);
807 } else if ((token.s[0] == '+' || token.s[0] == '-') 816 } else if ((token.s[0] == '+' || token.s[0] == '-')
808 && code.len > 0 && code.s[code.len - 1] == token.s[0]) 817 && code.len > 0 && code.s[code.len - 1] == token.s[0])
809 ps.want_blank = true; 818 ps.want_blank = true;
810 819
811 if (ps.want_blank) 820 if (ps.want_blank)
812 buf_add_char(&code, ' '); 821 buf_add_char(&code, ' ');
813 buf_add_buf(&code, &token); 822 buf_add_buf(&code, &token);
814 ps.want_blank = false; 823 ps.want_blank = false;
815} 824}
816 825
817static void 826static void
818process_postfix_op(void) 827process_postfix_op(void)
819{ 828{
820 buf_add_buf(&code, &token); 829 buf_add_buf(&code, &token);
821 ps.want_blank = true; 830 ps.want_blank = true;
822} 831}
823 832
824static void 833static void
825process_comma(void) 834process_comma(void)
826{ 835{
827 ps.want_blank = code.len > 0; /* only put blank after comma if comma 836 ps.want_blank = code.len > 0; /* only put blank after comma if comma
828 * does not start the line */ 837 * does not start the line */
829 838
830 if (ps.in_decl && ps.ind_paren_level == 0 839 if (ps.in_decl && ps.ind_paren_level == 0
831 && !ps.line_has_func_def && !ps.in_init && !ps.decl_indent_done) { 840 && !ps.line_has_func_def && !ps.in_init && !ps.decl_indent_done) {
832 /* indent leading commas and not the actual identifiers */ 841 /* indent leading commas and not the actual identifiers */
833 indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); 842 indent_declarator(ps.decl_ind - 1, ps.tabs_to_var);
834 } 843 }
835 844
836 buf_add_char(&code, ','); 845 buf_add_char(&code, ',');
837 846
838 if (ps.paren.len == 0) { 847 if (ps.paren.len == 0) {
839 if (ps.init_level == 0) 848 if (ps.init_level == 0)
840 ps.in_init = false; 849 ps.in_init = false;
841 int typical_varname_length = 8; 850 int typical_varname_length = 8;
842 if (ps.break_after_comma && (opt.break_after_comma || 851 if (ps.break_after_comma && (opt.break_after_comma ||
843 ind_add(compute_code_indent(), code.s, code.len) 852 ind_add(compute_code_indent(), code.s, code.len)
844 >= opt.max_line_length - typical_varname_length)) 853 >= opt.max_line_length - typical_varname_length))
845 ps.want_newline = true; 854 ps.want_newline = true;
846 } 855 }
847} 856}
848 857
849static void 858static void
850process_label_colon(void) 859process_label_colon(void)
851{ 860{
852 buf_add_buf(&lab, &code); 861 buf_add_buf(&lab, &code);
853 buf_add_char(&lab, ':'); 862 buf_add_char(&lab, ':');
854 buf_clear(&code); 863 buf_clear(&code);
855 864
856 if (ps.seen_case) 865 if (ps.seen_case)
857 out.line_kind = lk_case_or_default; 866 out.line_kind = lk_case_or_default;
858 ps.in_stmt_or_decl = false; 867 ps.in_stmt_or_decl = false;
859 ps.want_newline = ps.seen_case; 868 ps.want_newline = ps.seen_case;
860 ps.seen_case = false; 869 ps.seen_case = false;
861 ps.want_blank = false; 870 ps.want_blank = false;
862} 871}
863 872
864static void 873static void
865process_other_colon(void) 874process_other_colon(void)
866{ 875{
867 buf_add_char(&code, ':'); 876 buf_add_char(&code, ':');
868 ps.want_blank = ps.decl_level == 0; 877 ps.want_blank = ps.decl_level == 0;
869} 878}
870 879
871static void 880static void
872process_semicolon(void) 881process_semicolon(void)
873{ 882{
874 if (out.line_kind == lk_stmt_head) 883 if (out.line_kind == lk_stmt_head)
875 out.line_kind = lk_other; 884 out.line_kind = lk_other;
876 if (ps.decl_level == 0) { 885 if (ps.decl_level == 0) {
877 ps.in_var_decl = false; 886 ps.in_var_decl = false;
878 ps.in_typedef_decl = false; 887 ps.in_typedef_decl = false;
879 } 888 }
880 ps.seen_case = false; /* only needs to be reset on error */ 889 ps.seen_case = false; /* only needs to be reset on error */
881 ps.quest_level = 0; /* only needs to be reset on error */ 890 ps.quest_level = 0; /* only needs to be reset on error */
882 if (ps.prev_lsym == lsym_rparen) 891 if (ps.prev_lsym == lsym_rparen)
883 ps.in_func_def_params = false; 892 ps.in_func_def_params = false;
884 ps.in_init = false; 893 ps.in_init = false;
885 ps.init_level = 0; 894 ps.init_level = 0;
886 ps.declaration = ps.declaration == decl_begin ? decl_end : decl_no; 895 ps.declaration = ps.declaration == decl_begin ? decl_end : decl_no;
887 896
888 if (ps.in_decl && code.len == 0 && !ps.in_init && 897 if (ps.in_decl && code.len == 0 && !ps.in_init &&
889 !ps.decl_indent_done && ps.ind_paren_level == 0) { 898 !ps.decl_indent_done && ps.ind_paren_level == 0) {
890 /* indent stray semicolons in declarations */ 899 /* indent stray semicolons in declarations */
891 indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); 900 indent_declarator(ps.decl_ind - 1, ps.tabs_to_var);
892 } 901 }
893 902
894 ps.in_decl = ps.decl_level > 0; /* if we were in a first level 903 ps.in_decl = ps.decl_level > 0; /* if we were in a first level
895 * structure declaration before, we 904 * structure declaration before, we
896 * aren't anymore */ 905 * aren't anymore */
897 906
898 if (ps.paren.len > 0 && ps.spaced_expr_psym != psym_for_exprs) { 907 if (ps.paren.len > 0 && ps.spaced_expr_psym != psym_for_exprs) {
899 diag(1, "Unbalanced parentheses"); 908 diag(1, "Unbalanced parentheses");
900 ps.paren.len = 0; 909 ps.paren.len = 0;
901 if (ps.spaced_expr_psym != psym_0) { 910 if (ps.spaced_expr_psym != psym_0) {
902 parse(ps.spaced_expr_psym); 911 parse(ps.spaced_expr_psym);
903 ps.spaced_expr_psym = psym_0; 912 ps.spaced_expr_psym = psym_0;
904 } 913 }
905 } 914 }
906 buf_add_char(&code, ';'); 915 buf_add_char(&code, ';');
907 ps.want_blank = true; 916 ps.want_blank = true;
908 ps.in_stmt_or_decl = ps.paren.len > 0; 917 ps.in_stmt_or_decl = ps.paren.len > 0;
909 ps.decl_ind = 0; 918 ps.decl_ind = 0;
910 919
911 if (ps.spaced_expr_psym == psym_0) { 920 if (ps.spaced_expr_psym == psym_0) {
912 parse(psym_stmt); 921 parse(psym_stmt);
913 ps.want_newline = true; 922 ps.want_newline = true;
914 } 923 }
915} 924}
916 925
917static void 926static void
918process_type_outside_parentheses(void) 927process_type_outside_parentheses(void)
919{ 928{
920 parse(psym_decl); /* let the parser worry about indentation */ 929 parse(psym_decl); /* let the parser worry about indentation */
921 930
922 if (ps.prev_lsym == lsym_rparen && ps.psyms.len <= 2 && code.len > 0) 931 if (ps.prev_lsym == lsym_rparen && ps.psyms.len <= 2 && code.len > 0)
923 output_line(); 932 output_line();
924 933
925 if (ps.in_func_def_params && opt.indent_parameters && 934 if (ps.in_func_def_params && opt.indent_parameters &&
926 ps.decl_level == 0) { 935 ps.decl_level == 0) {
927 ps.ind_level = ps.ind_level_follow = 1; 936 ps.ind_level = ps.ind_level_follow = 1;
928 ps.line_is_stmt_cont = false; 937 ps.line_is_stmt_cont = false;
929 } 938 }
930 939
931 ps.in_var_decl = /* maybe */ true; 940 ps.in_var_decl = /* maybe */ true;
932 ps.in_decl = true; 941 ps.in_decl = true;
933 ps.line_has_decl = ps.in_decl; 942 ps.line_has_decl = ps.in_decl;
934 if (ps.decl_level == 0) 943 if (ps.decl_level == 0)
935 ps.declaration = decl_begin; 944 ps.declaration = decl_begin;
936 945
937 int ind = ps.ind_level > 0 && ps.decl_level == 0 946 int ind = ps.ind_level > 0 && ps.decl_level == 0
938 ? opt.local_decl_indent /* local variable */ 947 ? opt.local_decl_indent /* local variable */
939 : opt.decl_indent; /* global variable, or member */ 948 : opt.decl_indent; /* global variable, or member */
940 if (ind == 0) { 949 if (ind == 0) {
941 int ind0 = code.len > 0 ? ind_add(0, code.s, code.len) + 1 : 0; 950 int ind0 = code.len > 0 ? ind_add(0, code.s, code.len) + 1 : 0;
942 ps.decl_ind = ind_add(ind0, token.s, token.len) + 1; 951 ps.decl_ind = ind_add(ind0, token.s, token.len) + 1;
943 } else 952 } else
944 ps.decl_ind = ind; 953 ps.decl_ind = ind;
945 ps.tabs_to_var = opt.use_tabs && ind > 0; 954 ps.tabs_to_var = opt.use_tabs && ind > 0;
946} 955}
947 956
948static void 957static void
949process_word(lexer_symbol lsym) 958process_word(lexer_symbol lsym)
950{ 959{
951 if (ps.in_decl) { 960 if (ps.in_decl) {
952 if (lsym == lsym_funcname) { 961 if (lsym == lsym_funcname) {
953 ps.in_decl = false; 962 ps.in_decl = false;
954 if (opt.procnames_start_line && code.len > 0) 963 if (opt.procnames_start_line && code.len > 0)
955 output_line(); 964 output_line();
956 else if (ps.want_blank) 965 else if (ps.want_blank)
957 buf_add_char(&code, ' '); 966 buf_add_char(&code, ' ');
958 ps.want_blank = false; 967 ps.want_blank = false;
959 } else if (ps.in_typedef_decl && ps.decl_level == 0) { 968 } else if (ps.in_typedef_decl && ps.decl_level == 0) {
960 /* Do not indent typedef declarators. */ 969 /* Do not indent typedef declarators. */
961 } else if (!ps.in_init && !ps.decl_indent_done && 970 } else if (!ps.in_init && !ps.decl_indent_done &&
962 ps.ind_paren_level == 0) { 971 ps.ind_paren_level == 0) {
963 if (opt.decl_indent == 0 972 if (opt.decl_indent == 0
964 && code.len > 0 && code.s[code.len - 1] == '}') 973 && code.len > 0 && code.s[code.len - 1] == '}')
965 ps.decl_ind = ind_add(0, code.s, code.len) + 1; 974 ps.decl_ind = ind_add(0, code.s, code.len) + 1;
966 indent_declarator(ps.decl_ind, ps.tabs_to_var); 975 indent_declarator(ps.decl_ind, ps.tabs_to_var);
967 } 976 }
968 977
969 } else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { 978 } else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) {
970 parse(ps.spaced_expr_psym); 979 parse(ps.spaced_expr_psym);
971 ps.spaced_expr_psym = psym_0; 980 ps.spaced_expr_psym = psym_0;
972 ps.want_newline = true; 981 ps.want_newline = true;
973 ps.in_stmt_or_decl = false; 982 ps.in_stmt_or_decl = false;
974 ps.next_unary = true; 983 ps.next_unary = true;
975 } 984 }
976} 985}
977 986
978static void 987static void
979process_do(void) 988process_do(void)
980{ 989{
981 ps.in_stmt_or_decl = false; 990 ps.in_stmt_or_decl = false;
982 ps.in_decl = false; 991 ps.in_decl = false;
983 992
984 if (code.len > 0) 993 if (code.len > 0)
985 output_line(); 994 output_line();
986 995
987 parse(psym_do); 996 parse(psym_do);
988 ps.want_newline = true; 997 ps.want_newline = true;
989} 998}
990 999
991static void 1000static void
992process_else(void) 1001process_else(void)
993{ 1002{
994 ps.in_stmt_or_decl = false; 1003 ps.in_stmt_or_decl = false;
995 ps.in_decl = false; 1004 ps.in_decl = false;
996 1005
997 if (code.len > 0 1006 if (code.len > 0
998 && !(opt.cuddle_else && code.s[code.len - 1] == '}')) 1007 && !(opt.cuddle_else && code.s[code.len - 1] == '}'))
999 output_line(); 1008 output_line();
1000 1009
1001 parse(psym_else); 1010 parse(psym_else);
1002 ps.want_newline = true; 1011 ps.want_newline = true;
1003} 1012}
1004 1013
1005static void 1014static void
1006process_lsym(lexer_symbol lsym) 1015process_lsym(lexer_symbol lsym)
1007{ 1016{
1008 switch (lsym) { 1017 switch (lsym) {
1009 /* INDENT OFF */ 1018 /* INDENT OFF */
1010 case lsym_preprocessing: process_preprocessing(); break; 1019 case lsym_preprocessing: process_preprocessing(); break;
1011 case lsym_newline: process_newline(); break; 1020 case lsym_newline: process_newline(); break;
1012 case lsym_comment: process_comment(); break; 1021 case lsym_comment: process_comment(); break;
1013 case lsym_lparen: process_lparen(); break; 1022 case lsym_lparen: process_lparen(); break;
1014 case lsym_lbracket: process_lbracket(); break; 1023 case lsym_lbracket: process_lbracket(); break;
1015 case lsym_rparen: process_rparen(); break; 1024 case lsym_rparen: process_rparen(); break;
1016 case lsym_rbracket: process_rbracket(); break; 1025 case lsym_rbracket: process_rbracket(); break;
1017 case lsym_lbrace: process_lbrace(); break; 1026 case lsym_lbrace: process_lbrace(); break;
1018 case lsym_rbrace: process_rbrace(); break; 1027 case lsym_rbrace: process_rbrace(); break;
1019 case lsym_period: process_period(); break; 1028 case lsym_period: process_period(); break;
1020 case lsym_unary_op: process_unary_op(); break; 1029 case lsym_unary_op: process_unary_op(); break;
1021 case lsym_postfix_op: process_postfix_op(); break; 1030 case lsym_postfix_op: process_postfix_op(); break;
1022 case lsym_binary_op: goto copy_token; 1031 case lsym_binary_op: goto copy_token;
1023 case lsym_question: ps.quest_level++; goto copy_token; 1032 case lsym_question: ps.quest_level++; goto copy_token;
1024 case lsym_question_colon: goto copy_token; 1033 case lsym_question_colon: goto copy_token;
1025 case lsym_label_colon: process_label_colon(); break; 1034 case lsym_label_colon: process_label_colon(); break;
1026 case lsym_other_colon: process_other_colon(); break; 1035 case lsym_other_colon: process_other_colon(); break;
1027 case lsym_comma: process_comma(); break; 1036 case lsym_comma: process_comma(); break;
1028 case lsym_semicolon: process_semicolon(); break; 1037 case lsym_semicolon: process_semicolon(); break;
1029 case lsym_typedef: ps.in_typedef_decl = true; goto copy_token; 1038 case lsym_typedef: ps.in_typedef_decl = true; goto copy_token;
1030 case lsym_modifier: goto copy_token; 1039 case lsym_modifier: goto copy_token;
1031 case lsym_case: ps.seen_case = true; goto copy_token; 1040 case lsym_case: ps.seen_case = true; goto copy_token;
1032 case lsym_default: ps.seen_case = true; goto copy_token; 1041 case lsym_default: ps.seen_case = true; goto copy_token;
1033 case lsym_do: process_do(); goto copy_token; 1042 case lsym_do: process_do(); goto copy_token;
1034 case lsym_else: process_else(); goto copy_token; 1043 case lsym_else: process_else(); goto copy_token;
1035 case lsym_for: ps.spaced_expr_psym = psym_for_exprs; goto copy_token; 1044 case lsym_for: ps.spaced_expr_psym = psym_for_exprs; goto copy_token;
1036 case lsym_if: ps.spaced_expr_psym = psym_if_expr; goto copy_token; 1045 case lsym_if: ps.spaced_expr_psym = psym_if_expr; goto copy_token;
1037 case lsym_switch: ps.spaced_expr_psym = psym_switch_expr; goto copy_token; 1046 case lsym_switch: ps.spaced_expr_psym = psym_switch_expr; goto copy_token;
1038 case lsym_while: ps.spaced_expr_psym = psym_while_expr; goto copy_token; 1047 case lsym_while: ps.spaced_expr_psym = psym_while_expr; goto copy_token;
1039 /* INDENT ON */ 1048 /* INDENT ON */
1040 1049
1041 case lsym_tag: 1050 case lsym_tag:
1042 if (ps.paren.len > 0) 1051 if (ps.paren.len > 0)
1043 goto copy_token; 1052 goto copy_token;
1044 /* FALLTHROUGH */ 1053 /* FALLTHROUGH */
1045 case lsym_type_outside_parentheses: 1054 case lsym_type_outside_parentheses:
1046 process_type_outside_parentheses(); 1055 process_type_outside_parentheses();
1047 goto copy_token; 1056 goto copy_token;
1048 1057
1049 case lsym_type_in_parentheses: 1058 case lsym_type_in_parentheses:
1050 case lsym_sizeof: 1059 case lsym_sizeof:
1051 case lsym_offsetof: 1060 case lsym_offsetof:
1052 case lsym_word: 1061 case lsym_word:
1053 case lsym_funcname: 1062 case lsym_funcname:
1054 case lsym_return: 1063 case lsym_return:
1055 process_word(lsym); 1064 process_word(lsym);
1056copy_token: 1065copy_token:
1057 if (ps.want_blank) 1066 if (ps.want_blank)
1058 buf_add_char(&code, ' '); 1067 buf_add_char(&code, ' ');
1059 buf_add_buf(&code, &token); 1068 buf_add_buf(&code, &token);
1060 if (lsym != lsym_funcname) 1069 if (lsym != lsym_funcname)
1061 ps.want_blank = true; 1070 ps.want_blank = true;
1062 break; 1071 break;
1063 1072
1064 default: 1073 default:
1065 break; 1074 break;
1066 } 1075 }
1067} 1076}
1068 1077
1069static int 1078static int
1070indent(void) 1079indent(void)
1071{ 1080{
1072 debug_parser_state(); 1081 debug_parser_state();
1073 1082
1074 for (;;) { /* loop until we reach eof */ 1083 for (;;) { /* loop until we reach eof */
1075 lexer_symbol lsym = lexi(); 1084 lexer_symbol lsym = lexi();
1076 1085
1077 debug_blank_line(); 1086 debug_blank_line();
1078 debug_printf("line %d: %s", line_no, lsym_name[lsym]); 1087 debug_printf("line %d: %s", line_no, lsym_name[lsym]);
1079 debug_print_buf("token", &token); 1088 debug_print_buf("token", &token);
1080 debug_buffers(); 1089 debug_buffers();
1081 debug_blank_line(); 1090 debug_blank_line();
1082 1091
1083 if (lsym == lsym_eof) 1092 if (lsym == lsym_eof)
1084 return process_eof(); 1093 return process_eof();
1085 1094
1086 if (lsym == lsym_preprocessing || lsym == lsym_newline) 1095 if (lsym == lsym_preprocessing || lsym == lsym_newline)
1087 ps.want_newline = false; 1096 ps.want_newline = false;
1088 else if (lsym == lsym_comment) { 1097 else if (lsym == lsym_comment) {
1089 /* no special processing */ 1098 /* no special processing */
1090 } else { 1099 } else {
1091 if (lsym == lsym_if && ps.prev_lsym == lsym_else 1100 if (lsym == lsym_if && ps.prev_lsym == lsym_else
1092 && opt.else_if_in_same_line) 1101 && opt.else_if_in_same_line)
1093 ps.want_newline = false; 1102 ps.want_newline = false;
1094 1103
1095 if (ps.want_newline && should_break_line(lsym)) { 1104 if (ps.want_newline && should_break_line(lsym)) {
1096 ps.want_newline = false; 1105 ps.want_newline = false;
1097 output_line(); 1106 output_line();
1098 } 1107 }
1099 ps.in_stmt_or_decl = true; 1108 ps.in_stmt_or_decl = true;
1100 if (com.len > 0) 1109 if (com.len > 0)
1101 move_com_to_code(lsym); 1110 move_com_to_code(lsym);
1102 update_ps_lbrace_kind(lsym); 1111 update_ps_lbrace_kind(lsym);
1103 } 1112 }
1104 1113
1105 process_lsym(lsym); 1114 process_lsym(lsym);
1106 1115
1107 if (lsym != lsym_preprocessing 1116 if (lsym != lsym_preprocessing
1108 && lsym != lsym_newline 1117 && lsym != lsym_newline
1109 && lsym != lsym_comment) 1118 && lsym != lsym_comment)
1110 ps.prev_lsym = lsym; 1119 ps.prev_lsym = lsym;
1111 1120
1112 debug_parser_state(); 1121 debug_parser_state();
1113 } 1122 }
1114} 1123}
1115 1124
1116int 1125int
1117main(int argc, char **argv) 1126main(int argc, char **argv)
1118{ 1127{
1119 init_globals(); 1128 init_globals();
1120 load_profiles(argc, argv); 1129 load_profiles(argc, argv);
1121 parse_command_line(argc, argv); 1130 parse_command_line(argc, argv);
1122 set_initial_indentation(); 1131 set_initial_indentation();
1123 return indent(); 1132 return indent();
1124} 1133}