Sat Mar 13 13:14:14 2021 UTC ()
indent: fix handling of '/*' in string literal in preprocessing line

Previously, the '/*' in the string literal had been interpreted as the
beginning of a comment, which was wrong.  Because of that, the variable
declaration in the following line was still interpreted as part of the
comment.  The comment even continued until the end of the file.

Due to indent's forgiving nature, it neither complained nor even
mentioned that anything had gone wrong.  The decision of rather
producing wrong output than failing early is a dangerous one.

At least, there should have been an error message that at the end of the
file, the parser was still in a a comment, expecting the closing '*/'.


(rillig)
diff -r1.3 -r1.4 src/tests/usr.bin/indent/token-preprocessing.0.stdout
diff -r1.54 -r1.55 src/usr.bin/indent/indent.c

cvs diff -r1.3 -r1.4 src/tests/usr.bin/indent/Attic/token-preprocessing.0.stdout (switch to unified diff)

--- src/tests/usr.bin/indent/Attic/token-preprocessing.0.stdout 2021/03/13 13:04:13 1.3
+++ src/tests/usr.bin/indent/Attic/token-preprocessing.0.stdout 2021/03/13 13:14:14 1.4
@@ -1,39 +1,37 @@ @@ -1,39 +1,37 @@
1/* $NetBSD: token-preprocessing.0.stdout,v 1.3 2021/03/13 13:04:13 rillig Exp $ */ 1/* $NetBSD: token-preprocessing.0.stdout,v 1.4 2021/03/13 13:14:14 rillig Exp $ */
2/* $FreeBSD$ */ 2/* $FreeBSD$ */
3 3
4/*- 4/*-
5 * Tests for indenting preprocessing directives: 5 * Tests for indenting preprocessing directives:
6 * 6 *
7 * #define 7 * #define
8 * #ifdef 8 * #ifdef
9 * #pragma 9 * #pragma
10 * #line 10 * #line
11 */ 11 */
12 12
13#include <system-header.h> 13#include <system-header.h>
14#include "local-header.h" 14#include "local-header.h"
15 15
16#if 0 16#if 0
17#else 17#else
18#endif 18#endif
19 19
20#if 0 /* if comment */ 20#if 0 /* if comment */
21#else /* else comment */ 21#else /* else comment */
22#endif /* endif comment */ 22#endif /* endif comment */
23 23
24#if 0 /* outer if comment */ 24#if 0 /* outer if comment */
25/* $ XXX: The indentation is removed, which can get confusing */ 25/* $ XXX: The indentation is removed, which can get confusing */
26#if nested /* inner if comment */ 26#if nested /* inner if comment */
27#else /* inner else comment */ 27#else /* inner else comment */
28#endif /* inner endif comment */ 28#endif /* inner endif comment */
29#endif /* outer endif comment */ 29#endif /* outer endif comment */
30 30
31#define multi_line_definition /* first line 31#define multi_line_definition /* first line
32 * middle 32 * middle
33 * final line 33 * final line
34 */ actual_value 34 */ actual_value
35 35
36#define comment_in_string_literal "/* no comment " 36#define comment_in_string_literal "/* no comment "
37int this_is_an_ordinary_line_again; 37int this_is_an_ordinary_line_again;
38 
39/* $ FIXME: The above empty line is wrong. */ 

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

--- src/usr.bin/indent/indent.c 2021/03/13 12:52:24 1.54
+++ src/usr.bin/indent/indent.c 2021/03/13 13:14:14 1.55
@@ -1,1585 +1,1589 @@ @@ -1,1585 +1,1589 @@
1/* $NetBSD: indent.c,v 1.54 2021/03/13 12:52:24 rillig Exp $ */ 1/* $NetBSD: indent.c,v 1.55 2021/03/13 13:14:14 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#if 0 40#if 0
41#ifndef lint 41#ifndef lint
42static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; 42static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93";
43#endif /* not lint */ 43#endif /* not lint */
44#endif 44#endif
45 45
46#include <sys/cdefs.h> 46#include <sys/cdefs.h>
47#ifndef lint 47#ifndef lint
48#if defined(__NetBSD__) 48#if defined(__NetBSD__)
49__RCSID("$NetBSD: indent.c,v 1.54 2021/03/13 12:52:24 rillig Exp $"); 49__RCSID("$NetBSD: indent.c,v 1.55 2021/03/13 13:14:14 rillig Exp $");
50#elif defined(__FreeBSD__) 50#elif defined(__FreeBSD__)
51__FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $");
52#endif 52#endif
53#endif 53#endif
54 54
55#include <sys/param.h> 55#include <sys/param.h>
56#if HAVE_CAPSICUM 56#if HAVE_CAPSICUM
57#include <sys/capsicum.h> 57#include <sys/capsicum.h>
58#include <capsicum_helpers.h> 58#include <capsicum_helpers.h>
59#endif 59#endif
60#include <err.h> 60#include <err.h>
61#include <errno.h> 61#include <errno.h>
62#include <fcntl.h> 62#include <fcntl.h>
63#include <unistd.h> 63#include <unistd.h>
64#include <stdio.h> 64#include <stdio.h>
65#include <stdlib.h> 65#include <stdlib.h>
66#include <string.h> 66#include <string.h>
67#include <ctype.h> 67#include <ctype.h>
68 68
69#include "indent.h" 69#include "indent.h"
70 70
71struct options opt; 71struct options opt;
72struct parser_state ps; 72struct parser_state ps;
73 73
74char *labbuf; 74char *labbuf;
75char *s_lab; 75char *s_lab;
76char *e_lab; 76char *e_lab;
77char *l_lab; 77char *l_lab;
78 78
79char *codebuf; 79char *codebuf;
80char *s_code; 80char *s_code;
81char *e_code; 81char *e_code;
82char *l_code; 82char *l_code;
83 83
84char *combuf; 84char *combuf;
85char *s_com; 85char *s_com;
86char *e_com; 86char *e_com;
87char *l_com; 87char *l_com;
88 88
89char *tokenbuf; 89char *tokenbuf;
90char *s_token; 90char *s_token;
91char *e_token; 91char *e_token;
92char *l_token; 92char *l_token;
93 93
94char *in_buffer; 94char *in_buffer;
95char *in_buffer_limit; 95char *in_buffer_limit;
96char *buf_ptr; 96char *buf_ptr;
97char *buf_end; 97char *buf_end;
98 98
99char sc_buf[sc_size]; 99char sc_buf[sc_size];
100char *save_com; 100char *save_com;
101char *sc_end; 101char *sc_end;
102 102
103char *bp_save; 103char *bp_save;
104char *be_save; 104char *be_save;
105 105
106int found_err; 106int found_err;
107int n_real_blanklines; 107int n_real_blanklines;
108int prefix_blankline_requested; 108int prefix_blankline_requested;
109int postfix_blankline_requested; 109int postfix_blankline_requested;
110int break_comma; 110int break_comma;
111float case_ind; 111float case_ind;
112int code_lines; 112int code_lines;
113int had_eof; 113int had_eof;
114int line_no; 114int line_no;
115int inhibit_formatting; 115int inhibit_formatting;
116int suppress_blanklines; 116int suppress_blanklines;
117 117
118int ifdef_level; 118int ifdef_level;
119struct parser_state state_stack[5]; 119struct parser_state state_stack[5];
120struct parser_state match_state[5]; 120struct parser_state match_state[5];
121 121
122FILE *input; 122FILE *input;
123FILE *output; 123FILE *output;
124 124
125static void bakcopy(void); 125static void bakcopy(void);
126static void indent_declaration(int, int); 126static void indent_declaration(int, int);
127 127
128const char *in_name = "Standard Input"; /* will always point to name of input 128const char *in_name = "Standard Input"; /* will always point to name of input
129 * file */ 129 * file */
130const char *out_name = "Standard Output"; /* will always point to name 130const char *out_name = "Standard Output"; /* will always point to name
131 * of output file */ 131 * of output file */
132const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup 132const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup
133 * files */ 133 * files */
134char bakfile[MAXPATHLEN] = ""; 134char bakfile[MAXPATHLEN] = "";
135 135
136static void 136static void
137check_size_code(size_t desired_size) 137check_size_code(size_t desired_size)
138{ 138{
139 if (e_code + (desired_size) < l_code) 139 if (e_code + (desired_size) < l_code)
140 return; 140 return;
141 141
142 size_t nsize = l_code - s_code + 400 + desired_size; 142 size_t nsize = l_code - s_code + 400 + desired_size;
143 size_t code_len = e_code - s_code; 143 size_t code_len = e_code - s_code;
144 codebuf = realloc(codebuf, nsize); 144 codebuf = realloc(codebuf, nsize);
145 if (codebuf == NULL) 145 if (codebuf == NULL)
146 err(1, NULL); 146 err(1, NULL);
147 e_code = codebuf + code_len + 1; 147 e_code = codebuf + code_len + 1;
148 l_code = codebuf + nsize - 5; 148 l_code = codebuf + nsize - 5;
149 s_code = codebuf + 1; 149 s_code = codebuf + 1;
150} 150}
151 151
152static void 152static void
153check_size_label(size_t desired_size) 153check_size_label(size_t desired_size)
154{ 154{
155 if (e_lab + (desired_size) < l_lab) 155 if (e_lab + (desired_size) < l_lab)
156 return; 156 return;
157 157
158 size_t nsize = l_lab - s_lab + 400 + desired_size; 158 size_t nsize = l_lab - s_lab + 400 + desired_size;
159 size_t label_len = e_lab - s_lab; 159 size_t label_len = e_lab - s_lab;
160 labbuf = realloc(labbuf, nsize); 160 labbuf = realloc(labbuf, nsize);
161 if (labbuf == NULL) 161 if (labbuf == NULL)
162 err(1, NULL); 162 err(1, NULL);
163 e_lab = labbuf + label_len + 1; 163 e_lab = labbuf + label_len + 1;
164 l_lab = labbuf + nsize - 5; 164 l_lab = labbuf + nsize - 5;
165 s_lab = labbuf + 1; 165 s_lab = labbuf + 1;
166} 166}
167 167
168#if HAVE_CAPSICUM 168#if HAVE_CAPSICUM
169static void 169static void
170init_capsicum(void) 170init_capsicum(void)
171{ 171{
172 cap_rights_t rights; 172 cap_rights_t rights;
173 173
174 /* Restrict input/output descriptors and enter Capsicum sandbox. */ 174 /* Restrict input/output descriptors and enter Capsicum sandbox. */
175 cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); 175 cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE);
176 if (caph_rights_limit(fileno(output), &rights) < 0) 176 if (caph_rights_limit(fileno(output), &rights) < 0)
177 err(EXIT_FAILURE, "unable to limit rights for %s", out_name); 177 err(EXIT_FAILURE, "unable to limit rights for %s", out_name);
178 cap_rights_init(&rights, CAP_FSTAT, CAP_READ); 178 cap_rights_init(&rights, CAP_FSTAT, CAP_READ);
179 if (caph_rights_limit(fileno(input), &rights) < 0) 179 if (caph_rights_limit(fileno(input), &rights) < 0)
180 err(EXIT_FAILURE, "unable to limit rights for %s", in_name); 180 err(EXIT_FAILURE, "unable to limit rights for %s", in_name);
181 if (caph_enter() < 0) 181 if (caph_enter() < 0)
182 err(EXIT_FAILURE, "unable to enter capability mode"); 182 err(EXIT_FAILURE, "unable to enter capability mode");
183} 183}
184#endif 184#endif
185 185
186static void 186static void
187search_brace(token_type *inout_type_code, int *inout_force_nl, 187search_brace(token_type *inout_type_code, int *inout_force_nl,
188 int *inout_comment_buffered, int *inout_last_else) 188 int *inout_comment_buffered, int *inout_last_else)
189{ 189{
190 while (ps.search_brace) { 190 while (ps.search_brace) {
191 switch (*inout_type_code) { 191 switch (*inout_type_code) {
192 case newline: 192 case newline:
193 if (sc_end == NULL) { 193 if (sc_end == NULL) {
194 save_com = sc_buf; 194 save_com = sc_buf;
195 save_com[0] = save_com[1] = ' '; 195 save_com[0] = save_com[1] = ' ';
196 sc_end = &save_com[2]; 196 sc_end = &save_com[2];
197 } 197 }
198 *sc_end++ = '\n'; 198 *sc_end++ = '\n';
199 /* 199 /*
200 * We may have inherited a force_nl == true from the previous 200 * We may have inherited a force_nl == true from the previous
201 * token (like a semicolon). But once we know that a newline 201 * token (like a semicolon). But once we know that a newline
202 * has been scanned in this loop, force_nl should be false. 202 * has been scanned in this loop, force_nl should be false.
203 * 203 *
204 * However, the force_nl == true must be preserved if newline 204 * However, the force_nl == true must be preserved if newline
205 * is never scanned in this loop, so this assignment cannot be 205 * is never scanned in this loop, so this assignment cannot be
206 * done earlier. 206 * done earlier.
207 */ 207 */
208 *inout_force_nl = false; 208 *inout_force_nl = false;
209 case form_feed: 209 case form_feed:
210 break; 210 break;
211 case comment: 211 case comment:
212 if (sc_end == NULL) { 212 if (sc_end == NULL) {
213 /* 213 /*
214 * Copy everything from the start of the line, because 214 * Copy everything from the start of the line, because
215 * pr_comment() will use that to calculate original 215 * pr_comment() will use that to calculate original
216 * indentation of a boxed comment. 216 * indentation of a boxed comment.
217 */ 217 */
218 memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4); 218 memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4);
219 save_com = sc_buf + (buf_ptr - in_buffer - 4); 219 save_com = sc_buf + (buf_ptr - in_buffer - 4);
220 save_com[0] = save_com[1] = ' '; 220 save_com[0] = save_com[1] = ' ';
221 sc_end = &save_com[2]; 221 sc_end = &save_com[2];
222 } 222 }
223 *inout_comment_buffered = true; 223 *inout_comment_buffered = true;
224 *sc_end++ = '/'; /* copy in start of comment */ 224 *sc_end++ = '/'; /* copy in start of comment */
225 *sc_end++ = '*'; 225 *sc_end++ = '*';
226 for (;;) { /* loop until the end of the comment */ 226 for (;;) { /* loop until the end of the comment */
227 *sc_end = *buf_ptr++; 227 *sc_end = *buf_ptr++;
228 if (buf_ptr >= buf_end) 228 if (buf_ptr >= buf_end)
229 fill_buffer(); 229 fill_buffer();
230 if (*sc_end++ == '*' && *buf_ptr == '/') 230 if (*sc_end++ == '*' && *buf_ptr == '/')
231 break; /* we are at end of comment */ 231 break; /* we are at end of comment */
232 if (sc_end >= &save_com[sc_size]) { /* check for temp buffer 232 if (sc_end >= &save_com[sc_size]) { /* check for temp buffer
233 * overflow */ 233 * overflow */
234 diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); 234 diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever");
235 fflush(output); 235 fflush(output);
236 exit(1); 236 exit(1);
237 } 237 }
238 } 238 }
239 *sc_end++ = '/'; /* add ending slash */ 239 *sc_end++ = '/'; /* add ending slash */
240 if (++buf_ptr >= buf_end) /* get past / in buffer */ 240 if (++buf_ptr >= buf_end) /* get past / in buffer */
241 fill_buffer(); 241 fill_buffer();
242 break; 242 break;
243 case lbrace: 243 case lbrace:
244 /* 244 /*
245 * Put KNF-style lbraces before the buffered up tokens and 245 * Put KNF-style lbraces before the buffered up tokens and
246 * jump out of this loop in order to avoid copying the token 246 * jump out of this loop in order to avoid copying the token
247 * again under the default case of the switch below. 247 * again under the default case of the switch below.
248 */ 248 */
249 if (sc_end != NULL && opt.btype_2) { 249 if (sc_end != NULL && opt.btype_2) {
250 save_com[0] = '{'; 250 save_com[0] = '{';
251 /* 251 /*
252 * Originally the lbrace may have been alone on its own 252 * Originally the lbrace may have been alone on its own
253 * line, but it will be moved into "the else's line", so 253 * line, but it will be moved into "the else's line", so
254 * if there was a newline resulting from the "{" before, 254 * if there was a newline resulting from the "{" before,
255 * it must be scanned now and ignored. 255 * it must be scanned now and ignored.
256 */ 256 */
257 while (isspace((unsigned char)*buf_ptr)) { 257 while (isspace((unsigned char)*buf_ptr)) {
258 if (++buf_ptr >= buf_end) 258 if (++buf_ptr >= buf_end)
259 fill_buffer(); 259 fill_buffer();
260 if (*buf_ptr == '\n') 260 if (*buf_ptr == '\n')
261 break; 261 break;
262 } 262 }
263 goto sw_buffer; 263 goto sw_buffer;
264 } 264 }
265 /* FALLTHROUGH */ 265 /* FALLTHROUGH */
266 default: /* it is the start of a normal statement */ 266 default: /* it is the start of a normal statement */
267 { 267 {
268 int remove_newlines; 268 int remove_newlines;
269 269
270 remove_newlines = 270 remove_newlines =
271 /* "} else" */ 271 /* "} else" */
272 (*inout_type_code == keyword_do_else && *token == 'e' && 272 (*inout_type_code == keyword_do_else && *token == 'e' &&
273 e_code != s_code && e_code[-1] == '}') 273 e_code != s_code && e_code[-1] == '}')
274 /* "else if" */ 274 /* "else if" */
275 || (*inout_type_code == keyword_for_if_while && 275 || (*inout_type_code == keyword_for_if_while &&
276 *token == 'i' && *inout_last_else && opt.else_if); 276 *token == 'i' && *inout_last_else && opt.else_if);
277 if (remove_newlines) 277 if (remove_newlines)
278 *inout_force_nl = false; 278 *inout_force_nl = false;
279 if (sc_end == NULL) { /* ignore buffering if 279 if (sc_end == NULL) { /* ignore buffering if
280 * comment wasn't saved up */ 280 * comment wasn't saved up */
281 ps.search_brace = false; 281 ps.search_brace = false;
282 return; 282 return;
283 } 283 }
284 while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) { 284 while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) {
285 sc_end--; 285 sc_end--;
286 } 286 }
287 if (opt.swallow_optional_blanklines || 287 if (opt.swallow_optional_blanklines ||
288 (!*inout_comment_buffered && remove_newlines)) { 288 (!*inout_comment_buffered && remove_newlines)) {
289 *inout_force_nl = !remove_newlines; 289 *inout_force_nl = !remove_newlines;
290 while (sc_end > save_com && sc_end[-1] == '\n') { 290 while (sc_end > save_com && sc_end[-1] == '\n') {
291 sc_end--; 291 sc_end--;
292 } 292 }
293 } 293 }
294 if (*inout_force_nl) { /* if we should insert a nl here, put 294 if (*inout_force_nl) { /* if we should insert a nl here, put
295 * it into the buffer */ 295 * it into the buffer */
296 *inout_force_nl = false; 296 *inout_force_nl = false;
297 --line_no; /* this will be re-increased when the 297 --line_no; /* this will be re-increased when the
298 * newline is read from the buffer */ 298 * newline is read from the buffer */
299 *sc_end++ = '\n'; 299 *sc_end++ = '\n';
300 *sc_end++ = ' '; 300 *sc_end++ = ' ';
301 if (opt.verbose) /* print error msg if the line was 301 if (opt.verbose) /* print error msg if the line was
302 * not already broken */ 302 * not already broken */
303 diag(0, "Line broken"); 303 diag(0, "Line broken");
304 } 304 }
305 for (const char *t_ptr = token; *t_ptr; ++t_ptr) 305 for (const char *t_ptr = token; *t_ptr; ++t_ptr)
306 *sc_end++ = *t_ptr; 306 *sc_end++ = *t_ptr;
307 307
308 sw_buffer: 308 sw_buffer:
309 ps.search_brace = false; /* stop looking for start of stmt */ 309 ps.search_brace = false; /* stop looking for start of stmt */
310 bp_save = buf_ptr; /* save current input buffer */ 310 bp_save = buf_ptr; /* save current input buffer */
311 be_save = buf_end; 311 be_save = buf_end;
312 buf_ptr = save_com; /* fix so that subsequent calls to 312 buf_ptr = save_com; /* fix so that subsequent calls to
313 * lexi will take tokens out of save_com */ 313 * lexi will take tokens out of save_com */
314 *sc_end++ = ' '; /* add trailing blank, just in case */ 314 *sc_end++ = ' '; /* add trailing blank, just in case */
315 buf_end = sc_end; 315 buf_end = sc_end;
316 sc_end = NULL; 316 sc_end = NULL;
317 break; 317 break;
318 } 318 }
319 } /* end of switch */ 319 } /* end of switch */
320 /* 320 /*
321 * We must make this check, just in case there was an unexpected 321 * We must make this check, just in case there was an unexpected
322 * EOF. 322 * EOF.
323 */ 323 */
324 if (*inout_type_code != end_of_file) { 324 if (*inout_type_code != end_of_file) {
325 /* 325 /*
326 * The only intended purpose of calling lexi() below is to 326 * The only intended purpose of calling lexi() below is to
327 * categorize the next token in order to decide whether to 327 * categorize the next token in order to decide whether to
328 * continue buffering forthcoming tokens. Once the buffering 328 * continue buffering forthcoming tokens. Once the buffering
329 * is over, lexi() will be called again elsewhere on all of 329 * is over, lexi() will be called again elsewhere on all of
330 * the tokens - this time for normal processing. 330 * the tokens - this time for normal processing.
331 * 331 *
332 * Calling it for this purpose is a bug, because lexi() also 332 * Calling it for this purpose is a bug, because lexi() also
333 * changes the parser state and discards leading whitespace, 333 * changes the parser state and discards leading whitespace,
334 * which is needed mostly for comment-related considerations. 334 * which is needed mostly for comment-related considerations.
335 * 335 *
336 * Work around the former problem by giving lexi() a copy of 336 * Work around the former problem by giving lexi() a copy of
337 * the current parser state and discard it if the call turned 337 * the current parser state and discard it if the call turned
338 * out to be just a look ahead. 338 * out to be just a look ahead.
339 * 339 *
340 * Work around the latter problem by copying all whitespace 340 * Work around the latter problem by copying all whitespace
341 * characters into the buffer so that the later lexi() call 341 * characters into the buffer so that the later lexi() call
342 * will read them. 342 * will read them.
343 */ 343 */
344 if (sc_end != NULL) { 344 if (sc_end != NULL) {
345 while (*buf_ptr == ' ' || *buf_ptr == '\t') { 345 while (*buf_ptr == ' ' || *buf_ptr == '\t') {
346 *sc_end++ = *buf_ptr++; 346 *sc_end++ = *buf_ptr++;
347 if (sc_end >= &save_com[sc_size]) { 347 if (sc_end >= &save_com[sc_size]) {
348 errx(1, "input too long"); 348 errx(1, "input too long");
349 } 349 }
350 } 350 }
351 if (buf_ptr >= buf_end) { 351 if (buf_ptr >= buf_end) {
352 fill_buffer(); 352 fill_buffer();
353 } 353 }
354 } 354 }
355 355
356 struct parser_state transient_state; 356 struct parser_state transient_state;
357 transient_state = ps; 357 transient_state = ps;
358 *inout_type_code = lexi(&transient_state); /* read another token */ 358 *inout_type_code = lexi(&transient_state); /* read another token */
359 if (*inout_type_code != newline && *inout_type_code != form_feed && 359 if (*inout_type_code != newline && *inout_type_code != form_feed &&
360 *inout_type_code != comment && !transient_state.search_brace) { 360 *inout_type_code != comment && !transient_state.search_brace) {
361 ps = transient_state; 361 ps = transient_state;
362 } 362 }
363 } 363 }
364 } 364 }
365 365
366 *inout_last_else = 0; 366 *inout_last_else = 0;
367} 367}
368 368
369static void 369static void
370main_init_globals(void) 370main_init_globals(void)
371{ 371{
372 found_err = 0; 372 found_err = 0;
373 373
374 ps.p_stack[0] = stmt; /* this is the parser's stack */ 374 ps.p_stack[0] = stmt; /* this is the parser's stack */
375 ps.last_nl = true; /* this is true if the last thing scanned was 375 ps.last_nl = true; /* this is true if the last thing scanned was
376 * a newline */ 376 * a newline */
377 ps.last_token = semicolon; 377 ps.last_token = semicolon;
378 combuf = malloc(bufsize); 378 combuf = malloc(bufsize);
379 if (combuf == NULL) 379 if (combuf == NULL)
380 err(1, NULL); 380 err(1, NULL);
381 labbuf = malloc(bufsize); 381 labbuf = malloc(bufsize);
382 if (labbuf == NULL) 382 if (labbuf == NULL)
383 err(1, NULL); 383 err(1, NULL);
384 codebuf = malloc(bufsize); 384 codebuf = malloc(bufsize);
385 if (codebuf == NULL) 385 if (codebuf == NULL)
386 err(1, NULL); 386 err(1, NULL);
387 tokenbuf = malloc(bufsize); 387 tokenbuf = malloc(bufsize);
388 if (tokenbuf == NULL) 388 if (tokenbuf == NULL)
389 err(1, NULL); 389 err(1, NULL);
390 alloc_typenames(); 390 alloc_typenames();
391 init_constant_tt(); 391 init_constant_tt();
392 l_com = combuf + bufsize - 5; 392 l_com = combuf + bufsize - 5;
393 l_lab = labbuf + bufsize - 5; 393 l_lab = labbuf + bufsize - 5;
394 l_code = codebuf + bufsize - 5; 394 l_code = codebuf + bufsize - 5;
395 l_token = tokenbuf + bufsize - 5; 395 l_token = tokenbuf + bufsize - 5;
396 combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and 396 combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and
397 * comment buffers */ 397 * comment buffers */
398 combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; 398 combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0';
399 opt.else_if = 1; /* Default else-if special processing to on */ 399 opt.else_if = 1; /* Default else-if special processing to on */
400 s_lab = e_lab = labbuf + 1; 400 s_lab = e_lab = labbuf + 1;
401 s_code = e_code = codebuf + 1; 401 s_code = e_code = codebuf + 1;
402 s_com = e_com = combuf + 1; 402 s_com = e_com = combuf + 1;
403 s_token = e_token = tokenbuf + 1; 403 s_token = e_token = tokenbuf + 1;
404 404
405 in_buffer = malloc(10); 405 in_buffer = malloc(10);
406 if (in_buffer == NULL) 406 if (in_buffer == NULL)
407 err(1, NULL); 407 err(1, NULL);
408 in_buffer_limit = in_buffer + 8; 408 in_buffer_limit = in_buffer + 8;
409 buf_ptr = buf_end = in_buffer; 409 buf_ptr = buf_end = in_buffer;
410 line_no = 1; 410 line_no = 1;
411 had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; 411 had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;
412 ps.in_or_st = false; 412 ps.in_or_st = false;
413 ps.bl_line = true; 413 ps.bl_line = true;
414 ps.want_blank = ps.in_stmt = ps.ind_stmt = false; 414 ps.want_blank = ps.in_stmt = ps.ind_stmt = false;
415 415
416 ps.pcase = false; 416 ps.pcase = false;
417 sc_end = NULL; 417 sc_end = NULL;
418 bp_save = NULL; 418 bp_save = NULL;
419 be_save = NULL; 419 be_save = NULL;
420 420
421 output = NULL; 421 output = NULL;
422 422
423 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); 423 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX");
424 if (suffix != NULL) 424 if (suffix != NULL)
425 simple_backup_suffix = suffix; 425 simple_backup_suffix = suffix;
426} 426}
427 427
428static void 428static void
429main_parse_command_line(int argc, char **argv) 429main_parse_command_line(int argc, char **argv)
430{ 430{
431 int i; 431 int i;
432 const char *profile_name = NULL; 432 const char *profile_name = NULL;
433 433
434#if 0 434#if 0
435 max_line_length = 78; /* -l78 */ 435 max_line_length = 78; /* -l78 */
436 lineup_to_parens = 1; /* -lp */ 436 lineup_to_parens = 1; /* -lp */
437 lineup_to_parens_always = 0; /* -nlpl */ 437 lineup_to_parens_always = 0; /* -nlpl */
438 ps.ljust_decl = 0; /* -ndj */ 438 ps.ljust_decl = 0; /* -ndj */
439 ps.com_ind = 33; /* -c33 */ 439 ps.com_ind = 33; /* -c33 */
440 star_comment_cont = 1; /* -sc */ 440 star_comment_cont = 1; /* -sc */
441 ps.ind_size = 8; /* -i8 */ 441 ps.ind_size = 8; /* -i8 */
442 verbose = 0; 442 verbose = 0;
443 ps.decl_indent = 16; /* -di16 */ 443 ps.decl_indent = 16; /* -di16 */
444 ps.local_decl_indent = -1; /* if this is not set to some nonnegative value 444 ps.local_decl_indent = -1; /* if this is not set to some nonnegative value
445 * by an arg, we will set this equal to 445 * by an arg, we will set this equal to
446 * ps.decl_ind */ 446 * ps.decl_ind */
447 ps.indent_parameters = 1; /* -ip */ 447 ps.indent_parameters = 1; /* -ip */
448 ps.decl_com_ind = 0; /* if this is not set to some positive value 448 ps.decl_com_ind = 0; /* if this is not set to some positive value
449 * by an arg, we will set this equal to 449 * by an arg, we will set this equal to
450 * ps.com_ind */ 450 * ps.com_ind */
451 btype_2 = 1; /* -br */ 451 btype_2 = 1; /* -br */
452 cuddle_else = 1; /* -ce */ 452 cuddle_else = 1; /* -ce */
453 ps.unindent_displace = 0; /* -d0 */ 453 ps.unindent_displace = 0; /* -d0 */
454 ps.case_indent = 0; /* -cli0 */ 454 ps.case_indent = 0; /* -cli0 */
455 format_block_comments = 1; /* -fcb */ 455 format_block_comments = 1; /* -fcb */
456 format_col1_comments = 1; /* -fc1 */ 456 format_col1_comments = 1; /* -fc1 */
457 procnames_start_line = 1; /* -psl */ 457 procnames_start_line = 1; /* -psl */
458 proc_calls_space = 0; /* -npcs */ 458 proc_calls_space = 0; /* -npcs */
459 comment_delimiter_on_blankline = 1; /* -cdb */ 459 comment_delimiter_on_blankline = 1; /* -cdb */
460 ps.leave_comma = 1; /* -nbc */ 460 ps.leave_comma = 1; /* -nbc */
461#endif 461#endif
462 462
463 for (i = 1; i < argc; ++i) 463 for (i = 1; i < argc; ++i)
464 if (strcmp(argv[i], "-npro") == 0) 464 if (strcmp(argv[i], "-npro") == 0)
465 break; 465 break;
466 else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') 466 else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0')
467 profile_name = argv[i]; /* non-empty -P (set profile) */ 467 profile_name = argv[i]; /* non-empty -P (set profile) */
468 set_defaults(); 468 set_defaults();
469 if (i >= argc) 469 if (i >= argc)
470 set_profile(profile_name); 470 set_profile(profile_name);
471 471
472 for (i = 1; i < argc; ++i) { 472 for (i = 1; i < argc; ++i) {
473 473
474 /* 474 /*
475 * look thru args (if any) for changes to defaults 475 * look thru args (if any) for changes to defaults
476 */ 476 */
477 if (argv[i][0] != '-') {/* no flag on parameter */ 477 if (argv[i][0] != '-') {/* no flag on parameter */
478 if (input == NULL) { /* we must have the input file */ 478 if (input == NULL) { /* we must have the input file */
479 in_name = argv[i]; /* remember name of input file */ 479 in_name = argv[i]; /* remember name of input file */
480 input = fopen(in_name, "r"); 480 input = fopen(in_name, "r");
481 if (input == NULL) /* check for open error */ 481 if (input == NULL) /* check for open error */
482 err(1, "%s", in_name); 482 err(1, "%s", in_name);
483 continue; 483 continue;
484 } else if (output == NULL) { /* we have the output file */ 484 } else if (output == NULL) { /* we have the output file */
485 out_name = argv[i]; /* remember name of output file */ 485 out_name = argv[i]; /* remember name of output file */
486 if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite 486 if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite
487 * the file */ 487 * the file */
488 errx(1, "input and output files must be different"); 488 errx(1, "input and output files must be different");
489 } 489 }
490 output = fopen(out_name, "w"); 490 output = fopen(out_name, "w");
491 if (output == NULL) /* check for create error */ 491 if (output == NULL) /* check for create error */
492 err(1, "%s", out_name); 492 err(1, "%s", out_name);
493 continue; 493 continue;
494 } 494 }
495 errx(1, "unknown parameter: %s", argv[i]); 495 errx(1, "unknown parameter: %s", argv[i]);
496 } else 496 } else
497 set_option(argv[i]); 497 set_option(argv[i]);
498 } /* end of for */ 498 } /* end of for */
499 if (input == NULL) 499 if (input == NULL)
500 input = stdin; 500 input = stdin;
501 if (output == NULL) { 501 if (output == NULL) {
502 if (input == stdin) 502 if (input == stdin)
503 output = stdout; 503 output = stdout;
504 else { 504 else {
505 out_name = in_name; 505 out_name = in_name;
506 bakcopy(); 506 bakcopy();
507 } 507 }
508 } 508 }
509 509
510 if (opt.com_ind <= 1) 510 if (opt.com_ind <= 1)
511 opt.com_ind = 2; /* don't put normal comments before column 2 */ 511 opt.com_ind = 2; /* don't put normal comments before column 2 */
512 if (opt.block_comment_max_line_length <= 0) 512 if (opt.block_comment_max_line_length <= 0)
513 opt.block_comment_max_line_length = opt.max_line_length; 513 opt.block_comment_max_line_length = opt.max_line_length;
514 if (opt.local_decl_indent < 0) /* if not specified by user, set this */ 514 if (opt.local_decl_indent < 0) /* if not specified by user, set this */
515 opt.local_decl_indent = opt.decl_indent; 515 opt.local_decl_indent = opt.decl_indent;
516 if (opt.decl_com_ind <= 0) /* if not specified by user, set this */ 516 if (opt.decl_com_ind <= 0) /* if not specified by user, set this */
517 opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind; 517 opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind;
518 if (opt.continuation_indent == 0) 518 if (opt.continuation_indent == 0)
519 opt.continuation_indent = opt.ind_size; 519 opt.continuation_indent = opt.ind_size;
520} 520}
521 521
522static void 522static void
523main_prepare_parsing(void) 523main_prepare_parsing(void)
524{ 524{
525 fill_buffer(); /* get first batch of stuff into input buffer */ 525 fill_buffer(); /* get first batch of stuff into input buffer */
526 526
527 parse(semicolon); 527 parse(semicolon);
528 528
529 char *p = buf_ptr; 529 char *p = buf_ptr;
530 int col = 1; 530 int col = 1;
531 531
532 while (1) { 532 while (1) {
533 if (*p == ' ') 533 if (*p == ' ')
534 col++; 534 col++;
535 else if (*p == '\t') 535 else if (*p == '\t')
536 col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; 536 col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1;
537 else 537 else
538 break; 538 break;
539 p++; 539 p++;
540 } 540 }
541 if (col > opt.ind_size) 541 if (col > opt.ind_size)
542 ps.ind_level = ps.i_l_follow = col / opt.ind_size; 542 ps.ind_level = ps.i_l_follow = col / opt.ind_size;
543} 543}
544 544
545static void 545static void
546process_end_of_file(void) 546process_end_of_file(void)
547{ 547{
548 if (s_lab != e_lab || s_code != e_code || s_com != e_com) 548 if (s_lab != e_lab || s_code != e_code || s_com != e_com)
549 dump_line(); 549 dump_line();
550 550
551 if (ps.tos > 1) /* check for balanced braces */ 551 if (ps.tos > 1) /* check for balanced braces */
552 diag(1, "Stuff missing from end of file"); 552 diag(1, "Stuff missing from end of file");
553 553
554 if (opt.verbose) { 554 if (opt.verbose) {
555 printf("There were %d output lines and %d comments\n", 555 printf("There were %d output lines and %d comments\n",
556 ps.out_lines, ps.out_coms); 556 ps.out_lines, ps.out_coms);
557 printf("(Lines with comments)/(Lines with code): %6.3f\n", 557 printf("(Lines with comments)/(Lines with code): %6.3f\n",
558 (1.0 * ps.com_lines) / code_lines); 558 (1.0 * ps.com_lines) / code_lines);
559 } 559 }
560 560
561 fflush(output); 561 fflush(output);
562 exit(found_err); 562 exit(found_err);
563} 563}
564 564
565static void 565static void
566process_comment_in_code(token_type type_code, int *inout_force_nl) 566process_comment_in_code(token_type type_code, int *inout_force_nl)
567{ 567{
568 if (*inout_force_nl && 568 if (*inout_force_nl &&
569 type_code != semicolon && 569 type_code != semicolon &&
570 (type_code != lbrace || !opt.btype_2)) { 570 (type_code != lbrace || !opt.btype_2)) {
571 571
572 /* we should force a broken line here */ 572 /* we should force a broken line here */
573 if (opt.verbose) 573 if (opt.verbose)
574 diag(0, "Line broken"); 574 diag(0, "Line broken");
575 dump_line(); 575 dump_line();
576 ps.want_blank = false; /* dont insert blank at line start */ 576 ps.want_blank = false; /* dont insert blank at line start */
577 *inout_force_nl = false; 577 *inout_force_nl = false;
578 } 578 }
579 579
580 ps.in_stmt = true; /* turn on flag which causes an extra level of 580 ps.in_stmt = true; /* turn on flag which causes an extra level of
581 * indentation. this is turned off by a ; or 581 * indentation. this is turned off by a ; or
582 * '}' */ 582 * '}' */
583 if (s_com != e_com) { /* the turkey has embedded a comment 583 if (s_com != e_com) { /* the turkey has embedded a comment
584 * in a line. fix it */ 584 * in a line. fix it */
585 int len = e_com - s_com; 585 int len = e_com - s_com;
586 586
587 check_size_code(len + 3); 587 check_size_code(len + 3);
588 *e_code++ = ' '; 588 *e_code++ = ' ';
589 memcpy(e_code, s_com, len); 589 memcpy(e_code, s_com, len);
590 e_code += len; 590 e_code += len;
591 *e_code++ = ' '; 591 *e_code++ = ' ';
592 *e_code = '\0'; /* null terminate code sect */ 592 *e_code = '\0'; /* null terminate code sect */
593 ps.want_blank = false; 593 ps.want_blank = false;
594 e_com = s_com; 594 e_com = s_com;
595 } 595 }
596} 596}
597 597
598static void 598static void
599process_form_feed(void) 599process_form_feed(void)
600{ 600{
601 ps.use_ff = true; /* a form feed is treated much like a newline */ 601 ps.use_ff = true; /* a form feed is treated much like a newline */
602 dump_line(); 602 dump_line();
603 ps.want_blank = false; 603 ps.want_blank = false;
604} 604}
605 605
606static void 606static void
607process_newline(void) 607process_newline(void)
608{ 608{
609 if (ps.last_token != comma || ps.p_l_follow > 0 609 if (ps.last_token != comma || ps.p_l_follow > 0
610 || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { 610 || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) {
611 dump_line(); 611 dump_line();
612 ps.want_blank = false; 612 ps.want_blank = false;
613 } 613 }
614 ++line_no; /* keep track of input line number */ 614 ++line_no; /* keep track of input line number */
615} 615}
616 616
617static void 617static void
618process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw) 618process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw)
619{ 619{
620 /* count parens to make Healy happy */ 620 /* count parens to make Healy happy */
621 if (++ps.p_l_follow == nitems(ps.paren_indents)) { 621 if (++ps.p_l_follow == nitems(ps.paren_indents)) {
622 diag(0, "Reached internal limit of %zu unclosed parens", 622 diag(0, "Reached internal limit of %zu unclosed parens",
623 nitems(ps.paren_indents)); 623 nitems(ps.paren_indents));
624 ps.p_l_follow--; 624 ps.p_l_follow--;
625 } 625 }
626 if (*token == '[') 626 if (*token == '[')
627 /* not a function pointer declaration or a function call */; 627 /* not a function pointer declaration or a function call */;
628 else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && 628 else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent &&
629 ps.procname[0] == '\0' && ps.paren_level == 0) { 629 ps.procname[0] == '\0' && ps.paren_level == 0) {
630 /* function pointer declarations */ 630 /* function pointer declarations */
631 indent_declaration(dec_ind, tabs_to_var); 631 indent_declaration(dec_ind, tabs_to_var);
632 ps.dumped_decl_indent = true; 632 ps.dumped_decl_indent = true;
633 } else if (ps.want_blank && 633 } else if (ps.want_blank &&
634 ((ps.last_token != ident && ps.last_token != funcname) || 634 ((ps.last_token != ident && ps.last_token != funcname) ||
635 opt.proc_calls_space || 635 opt.proc_calls_space ||
636 (ps.keyword == rw_sizeof ? opt.Bill_Shannon : 636 (ps.keyword == rw_sizeof ? opt.Bill_Shannon :
637 ps.keyword != rw_0 && ps.keyword != rw_offsetof))) 637 ps.keyword != rw_0 && ps.keyword != rw_offsetof)))
638 *e_code++ = ' '; 638 *e_code++ = ' ';
639 ps.want_blank = false; 639 ps.want_blank = false;
640 *e_code++ = token[0]; 640 *e_code++ = token[0];
641 ps.paren_indents[ps.p_l_follow - 1] = 641 ps.paren_indents[ps.p_l_follow - 1] =
642 indentation_after_range(0, s_code, e_code); 642 indentation_after_range(0, s_code, e_code);
643 if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent 643 if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent
644 && ps.paren_indents[0] < 2 * opt.ind_size) 644 && ps.paren_indents[0] < 2 * opt.ind_size)
645 ps.paren_indents[0] = 2 * opt.ind_size; 645 ps.paren_indents[0] = 2 * opt.ind_size;
646 if (ps.in_or_st && *token == '(' && ps.tos <= 2) { 646 if (ps.in_or_st && *token == '(' && ps.tos <= 2) {
647 /* 647 /*
648 * this is a kluge to make sure that declarations will be 648 * this is a kluge to make sure that declarations will be
649 * aligned right if proc decl has an explicit type on it, i.e. 649 * aligned right if proc decl has an explicit type on it, i.e.
650 * "int a(x) {..." 650 * "int a(x) {..."
651 */ 651 */
652 parse(semicolon); /* I said this was a kluge... */ 652 parse(semicolon); /* I said this was a kluge... */
653 ps.in_or_st = false; /* turn off flag for structure decl or 653 ps.in_or_st = false; /* turn off flag for structure decl or
654 * initialization */ 654 * initialization */
655 } 655 }
656 /* parenthesized type following sizeof or offsetof is not a cast */ 656 /* parenthesized type following sizeof or offsetof is not a cast */
657 if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) 657 if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof)
658 ps.not_cast_mask |= 1 << ps.p_l_follow; 658 ps.not_cast_mask |= 1 << ps.p_l_follow;
659} 659}
660 660
661static void 661static void
662process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl, 662process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl,
663 token_type hd_type) 663 token_type hd_type)
664{ 664{
665 if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { 665 if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) {
666 ps.last_u_d = true; 666 ps.last_u_d = true;
667 ps.cast_mask &= (1 << ps.p_l_follow) - 1; 667 ps.cast_mask &= (1 << ps.p_l_follow) - 1;
668 ps.want_blank = opt.space_after_cast; 668 ps.want_blank = opt.space_after_cast;
669 } else 669 } else
670 ps.want_blank = true; 670 ps.want_blank = true;
671 ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; 671 ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;
672 672
673 if (--ps.p_l_follow < 0) { 673 if (--ps.p_l_follow < 0) {
674 ps.p_l_follow = 0; 674 ps.p_l_follow = 0;
675 diag(0, "Extra %c", *token); 675 diag(0, "Extra %c", *token);
676 } 676 }
677 677
678 if (e_code == s_code) /* if the paren starts the line */ 678 if (e_code == s_code) /* if the paren starts the line */
679 ps.paren_level = ps.p_l_follow; /* then indent it */ 679 ps.paren_level = ps.p_l_follow; /* then indent it */
680 680
681 *e_code++ = token[0]; 681 *e_code++ = token[0];
682 682
683 if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if 683 if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
684 * (...), or some such */ 684 * (...), or some such */
685 *inout_sp_sw = false; 685 *inout_sp_sw = false;
686 *inout_force_nl = true; /* must force newline after if */ 686 *inout_force_nl = true; /* must force newline after if */
687 ps.last_u_d = true; /* inform lexi that a following 687 ps.last_u_d = true; /* inform lexi that a following
688 * operator is unary */ 688 * operator is unary */
689 ps.in_stmt = false; /* dont use stmt continuation indentation */ 689 ps.in_stmt = false; /* dont use stmt continuation indentation */
690 690
691 parse(hd_type); /* let parser worry about if, or whatever */ 691 parse(hd_type); /* let parser worry about if, or whatever */
692 } 692 }
693 ps.search_brace = opt.btype_2; /* this should ensure that constructs such 693 ps.search_brace = opt.btype_2; /* this should ensure that constructs such
694 * as main(){...} and int[]{...} have their 694 * as main(){...} and int[]{...} have their
695 * braces put in the right place */ 695 * braces put in the right place */
696} 696}
697 697
698static void 698static void
699process_unary_op(int dec_ind, int tabs_to_var) 699process_unary_op(int dec_ind, int tabs_to_var)
700{ 700{
701 if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && 701 if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init &&
702 ps.procname[0] == '\0' && ps.paren_level == 0) { 702 ps.procname[0] == '\0' && ps.paren_level == 0) {
703 /* pointer declarations */ 703 /* pointer declarations */
704 704
705 /* 705 /*
706 * if this is a unary op in a declaration, we should indent 706 * if this is a unary op in a declaration, we should indent
707 * this token 707 * this token
708 */ 708 */
709 int i; 709 int i;
710 for (i = 0; token[i]; ++i) 710 for (i = 0; token[i]; ++i)
711 /* find length of token */; 711 /* find length of token */;
712 indent_declaration(dec_ind - i, tabs_to_var); 712 indent_declaration(dec_ind - i, tabs_to_var);
713 ps.dumped_decl_indent = true; 713 ps.dumped_decl_indent = true;
714 } else if (ps.want_blank) 714 } else if (ps.want_blank)
715 *e_code++ = ' '; 715 *e_code++ = ' ';
716 716
717 { 717 {
718 int len = e_token - s_token; 718 int len = e_token - s_token;
719 719
720 check_size_code(len); 720 check_size_code(len);
721 memcpy(e_code, token, len); 721 memcpy(e_code, token, len);
722 e_code += len; 722 e_code += len;
723 } 723 }
724 ps.want_blank = false; 724 ps.want_blank = false;
725} 725}
726 726
727static void 727static void
728process_binary_op(void) 728process_binary_op(void)
729{ 729{
730 int len = e_token - s_token; 730 int len = e_token - s_token;
731 731
732 check_size_code(len + 1); 732 check_size_code(len + 1);
733 if (ps.want_blank) 733 if (ps.want_blank)
734 *e_code++ = ' '; 734 *e_code++ = ' ';
735 memcpy(e_code, token, len); 735 memcpy(e_code, token, len);
736 e_code += len; 736 e_code += len;
737 737
738 ps.want_blank = true; 738 ps.want_blank = true;
739} 739}
740 740
741static void 741static void
742process_postfix_op(void) 742process_postfix_op(void)
743{ 743{
744 *e_code++ = token[0]; 744 *e_code++ = token[0];
745 *e_code++ = token[1]; 745 *e_code++ = token[1];
746 ps.want_blank = true; 746 ps.want_blank = true;
747} 747}
748 748
749static void 749static void
750process_question(int *inout_squest) 750process_question(int *inout_squest)
751{ 751{
752 (*inout_squest)++; /* this will be used when a later colon 752 (*inout_squest)++; /* this will be used when a later colon
753 * appears so we can distinguish the 753 * appears so we can distinguish the
754 * <c>?<n>:<n> construct */ 754 * <c>?<n>:<n> construct */
755 if (ps.want_blank) 755 if (ps.want_blank)
756 *e_code++ = ' '; 756 *e_code++ = ' ';
757 *e_code++ = '?'; 757 *e_code++ = '?';
758 ps.want_blank = true; 758 ps.want_blank = true;
759} 759}
760 760
761static void 761static void
762process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase) 762process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase)
763{ 763{
764 if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */ 764 if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */
765 --*inout_squest; 765 --*inout_squest;
766 if (ps.want_blank) 766 if (ps.want_blank)
767 *e_code++ = ' '; 767 *e_code++ = ' ';
768 *e_code++ = ':'; 768 *e_code++ = ':';
769 ps.want_blank = true; 769 ps.want_blank = true;
770 return; 770 return;
771 } 771 }
772 if (ps.in_or_st) { 772 if (ps.in_or_st) {
773 *e_code++ = ':'; 773 *e_code++ = ':';
774 ps.want_blank = false; 774 ps.want_blank = false;
775 return; 775 return;
776 } 776 }
777 ps.in_stmt = false; /* seeing a label does not imply we are in a 777 ps.in_stmt = false; /* seeing a label does not imply we are in a
778 * stmt */ 778 * stmt */
779 /* 779 /*
780 * turn everything so far into a label 780 * turn everything so far into a label
781 */ 781 */
782 { 782 {
783 int len = e_code - s_code; 783 int len = e_code - s_code;
784 784
785 check_size_label(len + 3); 785 check_size_label(len + 3);
786 memcpy(e_lab, s_code, len); 786 memcpy(e_lab, s_code, len);
787 e_lab += len; 787 e_lab += len;
788 *e_lab++ = ':'; 788 *e_lab++ = ':';
789 *e_lab = '\0'; 789 *e_lab = '\0';
790 e_code = s_code; 790 e_code = s_code;
791 } 791 }
792 *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by 792 *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by
793 * dump_line to decide how to 793 * dump_line to decide how to
794 * indent the label. force_nl 794 * indent the label. force_nl
795 * will force a case n: to be 795 * will force a case n: to be
796 * on a line by itself */ 796 * on a line by itself */
797 *inout_scase = false; 797 *inout_scase = false;
798 ps.want_blank = false; 798 ps.want_blank = false;
799} 799}
800 800
801static void 801static void
802process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind, 802process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind,
803 int const tabs_to_var, int *inout_sp_sw, 803 int const tabs_to_var, int *inout_sp_sw,
804 token_type const hd_type, 804 token_type const hd_type,
805 int *inout_force_nl) 805 int *inout_force_nl)
806{ 806{
807 if (ps.dec_nest == 0) 807 if (ps.dec_nest == 0)
808 ps.in_or_st = false; /* we are not in an initialization or 808 ps.in_or_st = false; /* we are not in an initialization or
809 * structure declaration */ 809 * structure declaration */
810 *inout_scase = false; /* these will only need resetting in an error */ 810 *inout_scase = false; /* these will only need resetting in an error */
811 *inout_squest = 0; 811 *inout_squest = 0;
812 if (ps.last_token == rparen) 812 if (ps.last_token == rparen)
813 ps.in_parameter_declaration = 0; 813 ps.in_parameter_declaration = 0;
814 ps.cast_mask = 0; 814 ps.cast_mask = 0;
815 ps.not_cast_mask = 0; 815 ps.not_cast_mask = 0;
816 ps.block_init = 0; 816 ps.block_init = 0;
817 ps.block_init_level = 0; 817 ps.block_init_level = 0;
818 ps.just_saw_decl--; 818 ps.just_saw_decl--;
819 819
820 if (ps.in_decl && s_code == e_code && !ps.block_init && 820 if (ps.in_decl && s_code == e_code && !ps.block_init &&
821 !ps.dumped_decl_indent && ps.paren_level == 0) { 821 !ps.dumped_decl_indent && ps.paren_level == 0) {
822 /* indent stray semicolons in declarations */ 822 /* indent stray semicolons in declarations */
823 indent_declaration(dec_ind - 1, tabs_to_var); 823 indent_declaration(dec_ind - 1, tabs_to_var);
824 ps.dumped_decl_indent = true; 824 ps.dumped_decl_indent = true;
825 } 825 }
826 826
827 ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level 827 ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level
828 * structure declaration, we 828 * structure declaration, we
829 * arent any more */ 829 * arent any more */
830 830
831 if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { 831 if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) {
832 832
833 /* 833 /*
834 * This should be true iff there were unbalanced parens in the 834 * This should be true iff there were unbalanced parens in the
835 * stmt. It is a bit complicated, because the semicolon might 835 * stmt. It is a bit complicated, because the semicolon might
836 * be in a for stmt 836 * be in a for stmt
837 */ 837 */
838 diag(1, "Unbalanced parens"); 838 diag(1, "Unbalanced parens");
839 ps.p_l_follow = 0; 839 ps.p_l_follow = 0;
840 if (*inout_sp_sw) { /* this is a check for an if, while, etc. with 840 if (*inout_sp_sw) { /* this is a check for an if, while, etc. with
841 * unbalanced parens */ 841 * unbalanced parens */
842 *inout_sp_sw = false; 842 *inout_sp_sw = false;
843 parse(hd_type); /* dont lose the if, or whatever */ 843 parse(hd_type); /* dont lose the if, or whatever */
844 } 844 }
845 } 845 }
846 *e_code++ = ';'; 846 *e_code++ = ';';
847 ps.want_blank = true; 847 ps.want_blank = true;
848 ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the 848 ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
849 * middle of a stmt */ 849 * middle of a stmt */
850 850
851 if (!*inout_sp_sw) { /* if not if for (;;) */ 851 if (!*inout_sp_sw) { /* if not if for (;;) */
852 parse(semicolon); /* let parser know about end of stmt */ 852 parse(semicolon); /* let parser know about end of stmt */
853 *inout_force_nl = true;/* force newline after an end of stmt */ 853 *inout_force_nl = true;/* force newline after an end of stmt */
854 } 854 }
855} 855}
856 856
857static void 857static void
858process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type, 858process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type,
859 int *di_stack, int di_stack_cap, int *inout_dec_ind) 859 int *di_stack, int di_stack_cap, int *inout_dec_ind)
860{ 860{
861 ps.in_stmt = false; /* dont indent the {} */ 861 ps.in_stmt = false; /* dont indent the {} */
862 if (!ps.block_init) 862 if (!ps.block_init)
863 *inout_force_nl = true; /* force other stuff on same line as '{' onto 863 *inout_force_nl = true; /* force other stuff on same line as '{' onto
864 * new line */ 864 * new line */
865 else if (ps.block_init_level <= 0) 865 else if (ps.block_init_level <= 0)
866 ps.block_init_level = 1; 866 ps.block_init_level = 1;
867 else 867 else
868 ps.block_init_level++; 868 ps.block_init_level++;
869 869
870 if (s_code != e_code && !ps.block_init) { 870 if (s_code != e_code && !ps.block_init) {
871 if (!opt.btype_2) { 871 if (!opt.btype_2) {
872 dump_line(); 872 dump_line();
873 ps.want_blank = false; 873 ps.want_blank = false;
874 } else if (ps.in_parameter_declaration && !ps.in_or_st) { 874 } else if (ps.in_parameter_declaration && !ps.in_or_st) {
875 ps.i_l_follow = 0; 875 ps.i_l_follow = 0;
876 if (opt.function_brace_split) { /* dump the line prior 876 if (opt.function_brace_split) { /* dump the line prior
877 * to the brace ... */ 877 * to the brace ... */
878 dump_line(); 878 dump_line();
879 ps.want_blank = false; 879 ps.want_blank = false;
880 } else /* add a space between the decl and brace */ 880 } else /* add a space between the decl and brace */
881 ps.want_blank = true; 881 ps.want_blank = true;
882 } 882 }
883 } 883 }
884 if (ps.in_parameter_declaration) 884 if (ps.in_parameter_declaration)
885 prefix_blankline_requested = 0; 885 prefix_blankline_requested = 0;
886 886
887 if (ps.p_l_follow > 0) { /* check for preceding unbalanced 887 if (ps.p_l_follow > 0) { /* check for preceding unbalanced
888 * parens */ 888 * parens */
889 diag(1, "Unbalanced parens"); 889 diag(1, "Unbalanced parens");
890 ps.p_l_follow = 0; 890 ps.p_l_follow = 0;
891 if (*inout_sp_sw) { /* check for unclosed if, for, etc. */ 891 if (*inout_sp_sw) { /* check for unclosed if, for, etc. */
892 *inout_sp_sw = false; 892 *inout_sp_sw = false;
893 parse(hd_type); 893 parse(hd_type);
894 ps.ind_level = ps.i_l_follow; 894 ps.ind_level = ps.i_l_follow;
895 } 895 }
896 } 896 }
897 if (s_code == e_code) 897 if (s_code == e_code)
898 ps.ind_stmt = false; /* dont put extra indentation on line 898 ps.ind_stmt = false; /* dont put extra indentation on line
899 * with '{' */ 899 * with '{' */
900 if (ps.in_decl && ps.in_or_st) { /* this is either a structure 900 if (ps.in_decl && ps.in_or_st) { /* this is either a structure
901 * declaration or an init */ 901 * declaration or an init */
902 di_stack[ps.dec_nest] = *inout_dec_ind; 902 di_stack[ps.dec_nest] = *inout_dec_ind;
903 if (++ps.dec_nest == di_stack_cap) { 903 if (++ps.dec_nest == di_stack_cap) {
904 diag(0, "Reached internal limit of %d struct levels", 904 diag(0, "Reached internal limit of %d struct levels",
905 di_stack_cap); 905 di_stack_cap);
906 ps.dec_nest--; 906 ps.dec_nest--;
907 } 907 }
908 /* ? dec_ind = 0; */ 908 /* ? dec_ind = 0; */
909 } else { 909 } else {
910 ps.decl_on_line = false; /* we can't be in the middle of 910 ps.decl_on_line = false; /* we can't be in the middle of
911 * a declaration, so don't do 911 * a declaration, so don't do
912 * special indentation of 912 * special indentation of
913 * comments */ 913 * comments */
914 if (opt.blanklines_after_declarations_at_proctop 914 if (opt.blanklines_after_declarations_at_proctop
915 && ps.in_parameter_declaration) 915 && ps.in_parameter_declaration)
916 postfix_blankline_requested = 1; 916 postfix_blankline_requested = 1;
917 ps.in_parameter_declaration = 0; 917 ps.in_parameter_declaration = 0;
918 ps.in_decl = false; 918 ps.in_decl = false;
919 } 919 }
920 *inout_dec_ind = 0; 920 *inout_dec_ind = 0;
921 parse(lbrace); /* let parser know about this */ 921 parse(lbrace); /* let parser know about this */
922 if (ps.want_blank) /* put a blank before '{' if '{' is not at 922 if (ps.want_blank) /* put a blank before '{' if '{' is not at
923 * start of line */ 923 * start of line */
924 *e_code++ = ' '; 924 *e_code++ = ' ';
925 ps.want_blank = false; 925 ps.want_blank = false;
926 *e_code++ = '{'; 926 *e_code++ = '{';
927 ps.just_saw_decl = 0; 927 ps.just_saw_decl = 0;
928} 928}
929 929
930static void 930static void
931process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack) 931process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack)
932{ 932{
933 if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be 933 if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be
934 * omitted in declarations */ 934 * omitted in declarations */
935 parse(semicolon); 935 parse(semicolon);
936 if (ps.p_l_follow) { /* check for unclosed if, for, else. */ 936 if (ps.p_l_follow) { /* check for unclosed if, for, else. */
937 diag(1, "Unbalanced parens"); 937 diag(1, "Unbalanced parens");
938 ps.p_l_follow = 0; 938 ps.p_l_follow = 0;
939 *inout_sp_sw = false; 939 *inout_sp_sw = false;
940 } 940 }
941 ps.just_saw_decl = 0; 941 ps.just_saw_decl = 0;
942 ps.block_init_level--; 942 ps.block_init_level--;
943 if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */ 943 if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */
944 if (opt.verbose) 944 if (opt.verbose)
945 diag(0, "Line broken"); 945 diag(0, "Line broken");
946 dump_line(); 946 dump_line();
947 } 947 }
948 *e_code++ = '}'; 948 *e_code++ = '}';
949 ps.want_blank = true; 949 ps.want_blank = true;
950 ps.in_stmt = ps.ind_stmt = false; 950 ps.in_stmt = ps.ind_stmt = false;
951 if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */ 951 if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */
952 *inout_dec_ind = di_stack[--ps.dec_nest]; 952 *inout_dec_ind = di_stack[--ps.dec_nest];
953 if (ps.dec_nest == 0 && !ps.in_parameter_declaration) 953 if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
954 ps.just_saw_decl = 2; 954 ps.just_saw_decl = 2;
955 ps.in_decl = true; 955 ps.in_decl = true;
956 } 956 }
957 prefix_blankline_requested = 0; 957 prefix_blankline_requested = 0;
958 parse(rbrace); /* let parser know about this */ 958 parse(rbrace); /* let parser know about this */
959 ps.search_brace = opt.cuddle_else 959 ps.search_brace = opt.cuddle_else
960 && ps.p_stack[ps.tos] == if_expr_stmt 960 && ps.p_stack[ps.tos] == if_expr_stmt
961 && ps.il[ps.tos] >= ps.ind_level; 961 && ps.il[ps.tos] >= ps.ind_level;
962 if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) 962 if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0)
963 postfix_blankline_requested = 1; 963 postfix_blankline_requested = 1;
964} 964}
965 965
966static void 966static void
967process_keyword_do_else(int *inout_force_nl, int *inout_last_else) 967process_keyword_do_else(int *inout_force_nl, int *inout_last_else)
968{ 968{
969 ps.in_stmt = false; 969 ps.in_stmt = false;
970 if (*token == 'e') { 970 if (*token == 'e') {
971 if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { 971 if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) {
972 if (opt.verbose) 972 if (opt.verbose)
973 diag(0, "Line broken"); 973 diag(0, "Line broken");
974 dump_line(); /* make sure this starts a line */ 974 dump_line(); /* make sure this starts a line */
975 ps.want_blank = false; 975 ps.want_blank = false;
976 } 976 }
977 *inout_force_nl = true;/* also, following stuff must go onto new line */ 977 *inout_force_nl = true;/* also, following stuff must go onto new line */
978 *inout_last_else = 1; 978 *inout_last_else = 1;
979 parse(keyword_else); 979 parse(keyword_else);
980 } else { 980 } else {
981 if (e_code != s_code) { /* make sure this starts a line */ 981 if (e_code != s_code) { /* make sure this starts a line */
982 if (opt.verbose) 982 if (opt.verbose)
983 diag(0, "Line broken"); 983 diag(0, "Line broken");
984 dump_line(); 984 dump_line();
985 ps.want_blank = false; 985 ps.want_blank = false;
986 } 986 }
987 *inout_force_nl = true;/* also, following stuff must go onto new line */ 987 *inout_force_nl = true;/* also, following stuff must go onto new line */
988 *inout_last_else = 0; 988 *inout_last_else = 0;
989 parse(keyword_do); 989 parse(keyword_do);
990 } 990 }
991} 991}
992 992
993static void 993static void
994process_decl(int *out_dec_ind, int *out_tabs_to_var) 994process_decl(int *out_dec_ind, int *out_tabs_to_var)
995{ 995{
996 parse(decl); /* let parser worry about indentation */ 996 parse(decl); /* let parser worry about indentation */
997 if (ps.last_token == rparen && ps.tos <= 1) { 997 if (ps.last_token == rparen && ps.tos <= 1) {
998 if (s_code != e_code) { 998 if (s_code != e_code) {
999 dump_line(); 999 dump_line();
1000 ps.want_blank = 0; 1000 ps.want_blank = 0;
1001 } 1001 }
1002 } 1002 }
1003 if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { 1003 if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) {
1004 ps.ind_level = ps.i_l_follow = 1; 1004 ps.ind_level = ps.i_l_follow = 1;
1005 ps.ind_stmt = 0; 1005 ps.ind_stmt = 0;
1006 } 1006 }
1007 ps.in_or_st = true; /* this might be a structure or initialization 1007 ps.in_or_st = true; /* this might be a structure or initialization
1008 * declaration */ 1008 * declaration */
1009 ps.in_decl = ps.decl_on_line = ps.last_token != type_def; 1009 ps.in_decl = ps.decl_on_line = ps.last_token != type_def;
1010 if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) 1010 if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
1011 ps.just_saw_decl = 2; 1011 ps.just_saw_decl = 2;
1012 prefix_blankline_requested = 0; 1012 prefix_blankline_requested = 0;
1013 int i; 1013 int i;
1014 for (i = 0; token[i++];); /* get length of token */ 1014 for (i = 0; token[i++];); /* get length of token */
1015 1015
1016 if (ps.ind_level == 0 || ps.dec_nest > 0) { 1016 if (ps.ind_level == 0 || ps.dec_nest > 0) {
1017 /* global variable or struct member in local variable */ 1017 /* global variable or struct member in local variable */
1018 *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; 1018 *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i;
1019 *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); 1019 *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0);
1020 } else { 1020 } else {
1021 /* local variable */ 1021 /* local variable */
1022 *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; 1022 *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i;
1023 *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); 1023 *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0);
1024 } 1024 }
1025} 1025}
1026 1026
1027static void 1027static void
1028process_ident(token_type type_code, int dec_ind, int tabs_to_var, 1028process_ident(token_type type_code, int dec_ind, int tabs_to_var,
1029 int *inout_sp_sw, int *inout_force_nl, token_type hd_type) 1029 int *inout_sp_sw, int *inout_force_nl, token_type hd_type)
1030{ 1030{
1031 if (ps.in_decl) { 1031 if (ps.in_decl) {
1032 if (type_code == funcname) { 1032 if (type_code == funcname) {
1033 ps.in_decl = false; 1033 ps.in_decl = false;
1034 if (opt.procnames_start_line && s_code != e_code) { 1034 if (opt.procnames_start_line && s_code != e_code) {
1035 *e_code = '\0'; 1035 *e_code = '\0';
1036 dump_line(); 1036 dump_line();
1037 } else if (ps.want_blank) { 1037 } else if (ps.want_blank) {
1038 *e_code++ = ' '; 1038 *e_code++ = ' ';
1039 } 1039 }
1040 ps.want_blank = false; 1040 ps.want_blank = false;
1041 } else if (!ps.block_init && !ps.dumped_decl_indent && 1041 } else if (!ps.block_init && !ps.dumped_decl_indent &&
1042 ps.paren_level == 0) { /* if we are in a declaration, we 1042 ps.paren_level == 0) { /* if we are in a declaration, we
1043 * must indent identifier */ 1043 * must indent identifier */
1044 indent_declaration(dec_ind, tabs_to_var); 1044 indent_declaration(dec_ind, tabs_to_var);
1045 ps.dumped_decl_indent = true; 1045 ps.dumped_decl_indent = true;
1046 ps.want_blank = false; 1046 ps.want_blank = false;
1047 } 1047 }
1048 } else if (*inout_sp_sw && ps.p_l_follow == 0) { 1048 } else if (*inout_sp_sw && ps.p_l_follow == 0) {
1049 *inout_sp_sw = false; 1049 *inout_sp_sw = false;
1050 *inout_force_nl = true; 1050 *inout_force_nl = true;
1051 ps.last_u_d = true; 1051 ps.last_u_d = true;
1052 ps.in_stmt = false; 1052 ps.in_stmt = false;
1053 parse(hd_type); 1053 parse(hd_type);
1054 } 1054 }
1055} 1055}
1056 1056
1057static void 1057static void
1058copy_id(void) 1058copy_id(void)
1059{ 1059{
1060 int len = e_token - s_token; 1060 int len = e_token - s_token;
1061 1061
1062 check_size_code(len + 1); 1062 check_size_code(len + 1);
1063 if (ps.want_blank) 1063 if (ps.want_blank)
1064 *e_code++ = ' '; 1064 *e_code++ = ' ';
1065 memcpy(e_code, s_token, len); 1065 memcpy(e_code, s_token, len);
1066 e_code += len; 1066 e_code += len;
1067} 1067}
1068 1068
1069static void 1069static void
1070process_string_prefix(void) 1070process_string_prefix(void)
1071{ 1071{
1072 int len = e_token - s_token; 1072 int len = e_token - s_token;
1073 1073
1074 check_size_code(len + 1); 1074 check_size_code(len + 1);
1075 if (ps.want_blank) 1075 if (ps.want_blank)
1076 *e_code++ = ' '; 1076 *e_code++ = ' ';
1077 memcpy(e_code, token, len); 1077 memcpy(e_code, token, len);
1078 e_code += len; 1078 e_code += len;
1079 1079
1080 ps.want_blank = false; 1080 ps.want_blank = false;
1081} 1081}
1082 1082
1083static void 1083static void
1084process_period(void) 1084process_period(void)
1085{ 1085{
1086 *e_code++ = '.'; /* move the period into line */ 1086 *e_code++ = '.'; /* move the period into line */
1087 ps.want_blank = false; /* dont put a blank after a period */ 1087 ps.want_blank = false; /* dont put a blank after a period */
1088} 1088}
1089 1089
1090static void 1090static void
1091process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl) 1091process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl)
1092{ 1092{
1093 ps.want_blank = (s_code != e_code); /* only put blank after comma 1093 ps.want_blank = (s_code != e_code); /* only put blank after comma
1094 * if comma does not start the line */ 1094 * if comma does not start the line */
1095 if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && 1095 if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init &&
1096 !ps.dumped_decl_indent && ps.paren_level == 0) { 1096 !ps.dumped_decl_indent && ps.paren_level == 0) {
1097 /* indent leading commas and not the actual identifiers */ 1097 /* indent leading commas and not the actual identifiers */
1098 indent_declaration(dec_ind - 1, tabs_to_var); 1098 indent_declaration(dec_ind - 1, tabs_to_var);
1099 ps.dumped_decl_indent = true; 1099 ps.dumped_decl_indent = true;
1100 } 1100 }
1101 *e_code++ = ','; 1101 *e_code++ = ',';
1102 if (ps.p_l_follow == 0) { 1102 if (ps.p_l_follow == 0) {
1103 if (ps.block_init_level <= 0) 1103 if (ps.block_init_level <= 0)
1104 ps.block_init = 0; 1104 ps.block_init = 0;
1105 if (break_comma && (!opt.leave_comma || 1105 if (break_comma && (!opt.leave_comma ||
1106 indentation_after_range( 1106 indentation_after_range(
1107 compute_code_indent(), s_code, e_code) 1107 compute_code_indent(), s_code, e_code)
1108 >= opt.max_line_length - opt.tabsize)) 1108 >= opt.max_line_length - opt.tabsize))
1109 *inout_force_nl = true; 1109 *inout_force_nl = true;
1110 } 1110 }
1111} 1111}
1112 1112
1113static void 1113static void
1114process_preprocessing(void) 1114process_preprocessing(void)
1115{ 1115{
1116 if (s_com != e_com || s_lab != e_lab || s_code != e_code) 1116 if (s_com != e_com || s_lab != e_lab || s_code != e_code)
1117 dump_line(); 1117 dump_line();
1118 check_size_label(1); 1118 check_size_label(1);
1119 *e_lab++ = '#'; /* move whole line to 'label' buffer */ 1119 *e_lab++ = '#'; /* move whole line to 'label' buffer */
1120 1120
1121 { 1121 {
1122 int in_comment = 0; 1122 int in_comment = 0;
1123 int com_start = 0; 1123 int com_start = 0;
1124 char quote = 0; 1124 char quote = '\0';
1125 int com_end = 0; 1125 int com_end = 0;
1126 1126
1127 while (*buf_ptr == ' ' || *buf_ptr == '\t') { 1127 while (*buf_ptr == ' ' || *buf_ptr == '\t') {
1128 buf_ptr++; 1128 buf_ptr++;
1129 if (buf_ptr >= buf_end) 1129 if (buf_ptr >= buf_end)
1130 fill_buffer(); 1130 fill_buffer();
1131 } 1131 }
1132 while (*buf_ptr != '\n' || (in_comment && !had_eof)) { 1132 while (*buf_ptr != '\n' || (in_comment && !had_eof)) {
1133 check_size_label(2); 1133 check_size_label(2);
1134 *e_lab = *buf_ptr++; 1134 *e_lab = *buf_ptr++;
1135 if (buf_ptr >= buf_end) 1135 if (buf_ptr >= buf_end)
1136 fill_buffer(); 1136 fill_buffer();
1137 switch (*e_lab++) { 1137 switch (*e_lab++) {
1138 case '\\': 1138 case '\\':
1139 if (!in_comment) { 1139 if (!in_comment) {
1140 *e_lab++ = *buf_ptr++; 1140 *e_lab++ = *buf_ptr++;
1141 if (buf_ptr >= buf_end) 1141 if (buf_ptr >= buf_end)
1142 fill_buffer(); 1142 fill_buffer();
1143 } 1143 }
1144 break; 1144 break;
1145 case '/': 1145 case '/':
1146 if (*buf_ptr == '*' && !in_comment && !quote) { 1146 if (*buf_ptr == '*' && !in_comment && quote == '\0') {
1147 in_comment = 1; 1147 in_comment = 1;
1148 *e_lab++ = *buf_ptr++; 1148 *e_lab++ = *buf_ptr++;
1149 com_start = e_lab - s_lab - 2; 1149 com_start = e_lab - s_lab - 2;
1150 } 1150 }
1151 break; 1151 break;
1152 case '"': 1152 case '"':
1153 if (quote == '"') 1153 if (quote == '"')
1154 quote = 0; 1154 quote = '\0';
 1155 else if (quote == '\0')
 1156 quote = '"';
1155 break; 1157 break;
1156 case '\'': 1158 case '\'':
1157 if (quote == '\'') 1159 if (quote == '\'')
1158 quote = 0; 1160 quote = '\0';
 1161 else if (quote == '\0')
 1162 quote = '\'';
1159 break; 1163 break;
1160 case '*': 1164 case '*':
1161 if (*buf_ptr == '/' && in_comment) { 1165 if (*buf_ptr == '/' && in_comment) {
1162 in_comment = 0; 1166 in_comment = 0;
1163 *e_lab++ = *buf_ptr++; 1167 *e_lab++ = *buf_ptr++;
1164 com_end = e_lab - s_lab; 1168 com_end = e_lab - s_lab;
1165 } 1169 }
1166 break; 1170 break;
1167 } 1171 }
1168 } 1172 }
1169 1173
1170 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 1174 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
1171 e_lab--; 1175 e_lab--;
1172 if (e_lab - s_lab == com_end && bp_save == NULL) { 1176 if (e_lab - s_lab == com_end && bp_save == NULL) {
1173 /* comment on preprocessor line */ 1177 /* comment on preprocessor line */
1174 if (sc_end == NULL) { /* if this is the first comment, 1178 if (sc_end == NULL) { /* if this is the first comment,
1175 * we must set up the buffer */ 1179 * we must set up the buffer */
1176 save_com = sc_buf; 1180 save_com = sc_buf;
1177 sc_end = &save_com[0]; 1181 sc_end = &save_com[0];
1178 } else { 1182 } else {
1179 *sc_end++ = '\n'; /* add newline between 1183 *sc_end++ = '\n'; /* add newline between
1180 * comments */ 1184 * comments */
1181 *sc_end++ = ' '; 1185 *sc_end++ = ' ';
1182 --line_no; 1186 --line_no;
1183 } 1187 }
1184 if (sc_end - save_com + com_end - com_start > sc_size) 1188 if (sc_end - save_com + com_end - com_start > sc_size)
1185 errx(1, "input too long"); 1189 errx(1, "input too long");
1186 memmove(sc_end, s_lab + com_start, com_end - com_start); 1190 memmove(sc_end, s_lab + com_start, com_end - com_start);
1187 sc_end += com_end - com_start; 1191 sc_end += com_end - com_start;
1188 e_lab = s_lab + com_start; 1192 e_lab = s_lab + com_start;
1189 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 1193 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
1190 e_lab--; 1194 e_lab--;
1191 bp_save = buf_ptr; /* save current input buffer */ 1195 bp_save = buf_ptr; /* save current input buffer */
1192 be_save = buf_end; 1196 be_save = buf_end;
1193 buf_ptr = save_com; /* fix so that subsequent calls to 1197 buf_ptr = save_com; /* fix so that subsequent calls to
1194 * lexi will take tokens out of 1198 * lexi will take tokens out of
1195 * save_com */ 1199 * save_com */
1196 *sc_end++ = ' '; /* add trailing blank, just in case */ 1200 *sc_end++ = ' '; /* add trailing blank, just in case */
1197 buf_end = sc_end; 1201 buf_end = sc_end;
1198 sc_end = NULL; 1202 sc_end = NULL;
1199 } 1203 }
1200 check_size_label(1); 1204 check_size_label(1);
1201 *e_lab = '\0'; /* null terminate line */ 1205 *e_lab = '\0'; /* null terminate line */
1202 ps.pcase = false; 1206 ps.pcase = false;
1203 } 1207 }
1204 1208
1205 if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ 1209 if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */
1206 if ((size_t)ifdef_level < nitems(state_stack)) { 1210 if ((size_t)ifdef_level < nitems(state_stack)) {
1207 match_state[ifdef_level].tos = -1; 1211 match_state[ifdef_level].tos = -1;
1208 state_stack[ifdef_level++] = ps; 1212 state_stack[ifdef_level++] = ps;
1209 } else 1213 } else
1210 diag(1, "#if stack overflow"); 1214 diag(1, "#if stack overflow");
1211 } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ 1215 } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */
1212 if (ifdef_level <= 0) 1216 if (ifdef_level <= 0)
1213 diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); 1217 diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");
1214 else { 1218 else {
1215 match_state[ifdef_level - 1] = ps; 1219 match_state[ifdef_level - 1] = ps;
1216 ps = state_stack[ifdef_level - 1]; 1220 ps = state_stack[ifdef_level - 1];
1217 } 1221 }
1218 } else if (strncmp(s_lab, "#endif", 6) == 0) { 1222 } else if (strncmp(s_lab, "#endif", 6) == 0) {
1219 if (ifdef_level <= 0) 1223 if (ifdef_level <= 0)
1220 diag(1, "Unmatched #endif"); 1224 diag(1, "Unmatched #endif");
1221 else 1225 else
1222 ifdef_level--; 1226 ifdef_level--;
1223 } else { 1227 } else {
1224 static const struct directives { 1228 static const struct directives {
1225 int size; 1229 int size;
1226 const char *string; 1230 const char *string;
1227 } recognized[] = { 1231 } recognized[] = {
1228 {7, "include"}, 1232 {7, "include"},
1229 {6, "define"}, 1233 {6, "define"},
1230 {5, "undef"}, 1234 {5, "undef"},
1231 {4, "line"}, 1235 {4, "line"},
1232 {5, "error"}, 1236 {5, "error"},
1233 {6, "pragma"} 1237 {6, "pragma"}
1234 }; 1238 };
1235 int d = nitems(recognized); 1239 int d = nitems(recognized);
1236 while (--d >= 0) 1240 while (--d >= 0)
1237 if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) 1241 if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0)
1238 break; 1242 break;
1239 if (d < 0) { 1243 if (d < 0) {
1240 diag(1, "Unrecognized cpp directive"); 1244 diag(1, "Unrecognized cpp directive");
1241 return; 1245 return;
1242 } 1246 }
1243 } 1247 }
1244 if (opt.blanklines_around_conditional_compilation) { 1248 if (opt.blanklines_around_conditional_compilation) {
1245 postfix_blankline_requested++; 1249 postfix_blankline_requested++;
1246 n_real_blanklines = 0; 1250 n_real_blanklines = 0;
1247 } else { 1251 } else {
1248 postfix_blankline_requested = 0; 1252 postfix_blankline_requested = 0;
1249 prefix_blankline_requested = 0; 1253 prefix_blankline_requested = 0;
1250 } 1254 }
1251 1255
1252 /* 1256 /*
1253 * subsequent processing of the newline character will cause the line to 1257 * subsequent processing of the newline character will cause the line to
1254 * be printed 1258 * be printed
1255 */ 1259 */
1256} 1260}
1257 1261
1258static void 1262static void
1259main_loop(void) 1263main_loop(void)
1260{ 1264{
1261 token_type type_code; 1265 token_type type_code;
1262 int force_nl; /* when true, code must be broken */ 1266 int force_nl; /* when true, code must be broken */
1263 int last_else = false; /* true iff last keyword was an else */ 1267 int last_else = false; /* true iff last keyword was an else */
1264 int dec_ind; /* current indentation for declarations */ 1268 int dec_ind; /* current indentation for declarations */
1265 int di_stack[20]; /* a stack of structure indentation levels */ 1269 int di_stack[20]; /* a stack of structure indentation levels */
1266 int tabs_to_var; /* true if using tabs to indent to var name */ 1270 int tabs_to_var; /* true if using tabs to indent to var name */
1267 int sp_sw; /* when true, we are in the expression of 1271 int sp_sw; /* when true, we are in the expression of
1268 * if(...), while(...), etc. */ 1272 * if(...), while(...), etc. */
1269 token_type hd_type = end_of_file; /* used to store type of stmt 1273 token_type hd_type = end_of_file; /* used to store type of stmt
1270 * for if (...), for (...), etc */ 1274 * for if (...), for (...), etc */
1271 int squest; /* when this is positive, we have seen a ? 1275 int squest; /* when this is positive, we have seen a ?
1272 * without the matching : in a <c>?<s>:<s> 1276 * without the matching : in a <c>?<s>:<s>
1273 * construct */ 1277 * construct */
1274 int scase; /* set to true when we see a case, so we will 1278 int scase; /* set to true when we see a case, so we will
1275 * know what to do with the following colon */ 1279 * know what to do with the following colon */
1276 1280
1277 sp_sw = force_nl = false; 1281 sp_sw = force_nl = false;
1278 dec_ind = 0; 1282 dec_ind = 0;
1279 di_stack[ps.dec_nest = 0] = 0; 1283 di_stack[ps.dec_nest = 0] = 0;
1280 scase = false; 1284 scase = false;
1281 squest = 0; 1285 squest = 0;
1282 tabs_to_var = 0; 1286 tabs_to_var = 0;
1283 1287
1284 while (1) { /* this is the main loop. it will go until we 1288 while (1) { /* this is the main loop. it will go until we
1285 * reach eof */ 1289 * reach eof */
1286 int comment_buffered = false; 1290 int comment_buffered = false;
1287 1291
1288 type_code = lexi(&ps); /* lexi reads one token. The actual 1292 type_code = lexi(&ps); /* lexi reads one token. The actual
1289 * characters read are stored in "token". lexi 1293 * characters read are stored in "token". lexi
1290 * returns a code indicating the type of token */ 1294 * returns a code indicating the type of token */
1291 1295
1292 /* 1296 /*
1293 * The following code moves newlines and comments following an if (), 1297 * The following code moves newlines and comments following an if (),
1294 * while (), else, etc. up to the start of the following stmt to 1298 * while (), else, etc. up to the start of the following stmt to
1295 * a buffer. This allows proper handling of both kinds of brace 1299 * a buffer. This allows proper handling of both kinds of brace
1296 * placement (-br, -bl) and cuddling "else" (-ce). 1300 * placement (-br, -bl) and cuddling "else" (-ce).
1297 */ 1301 */
1298 search_brace(&type_code, &force_nl, &comment_buffered, &last_else); 1302 search_brace(&type_code, &force_nl, &comment_buffered, &last_else);
1299 1303
1300 if (type_code == end_of_file) { 1304 if (type_code == end_of_file) {
1301 process_end_of_file(); 1305 process_end_of_file();
1302 return; 1306 return;
1303 } 1307 }
1304 1308
1305 if ( 1309 if (
1306 type_code != comment && 1310 type_code != comment &&
1307 type_code != newline && 1311 type_code != newline &&
1308 type_code != preprocessing && 1312 type_code != preprocessing &&
1309 type_code != form_feed) { 1313 type_code != form_feed) {
1310 process_comment_in_code(type_code, &force_nl); 1314 process_comment_in_code(type_code, &force_nl);
1311 1315
1312 } else if (type_code != comment) /* preserve force_nl thru a comment */ 1316 } else if (type_code != comment) /* preserve force_nl thru a comment */
1313 force_nl = false; /* cancel forced newline after newline, form 1317 force_nl = false; /* cancel forced newline after newline, form
1314 * feed, etc */ 1318 * feed, etc */
1315 1319
1316 1320
1317 1321
1318 /*-----------------------------------------------------*\ 1322 /*-----------------------------------------------------*\
1319 | do switch on type of token scanned | 1323 | do switch on type of token scanned |
1320 \*-----------------------------------------------------*/ 1324 \*-----------------------------------------------------*/
1321 check_size_code(3); /* maximum number of increments of e_code 1325 check_size_code(3); /* maximum number of increments of e_code
1322 * before the next check_size_code or 1326 * before the next check_size_code or
1323 * dump_line() is 2. After that there's the 1327 * dump_line() is 2. After that there's the
1324 * final increment for the null character. */ 1328 * final increment for the null character. */
1325 switch (type_code) { /* now, decide what to do with the token */ 1329 switch (type_code) { /* now, decide what to do with the token */
1326 1330
1327 case form_feed: /* found a form feed in line */ 1331 case form_feed: /* found a form feed in line */
1328 process_form_feed(); 1332 process_form_feed();
1329 break; 1333 break;
1330 1334
1331 case newline: 1335 case newline:
1332 process_newline(); 1336 process_newline();
1333 break; 1337 break;
1334 1338
1335 case lparen: /* got a '(' or '[' */ 1339 case lparen: /* got a '(' or '[' */
1336 process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw); 1340 process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw);
1337 break; 1341 break;
1338 1342
1339 case rparen: /* got a ')' or ']' */ 1343 case rparen: /* got a ')' or ']' */
1340 process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type); 1344 process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type);
1341 break; 1345 break;
1342 1346
1343 case unary_op: /* this could be any unary operation */ 1347 case unary_op: /* this could be any unary operation */
1344 process_unary_op(dec_ind, tabs_to_var); 1348 process_unary_op(dec_ind, tabs_to_var);
1345 break; 1349 break;
1346 1350
1347 case binary_op: /* any binary operation */ 1351 case binary_op: /* any binary operation */
1348 process_binary_op(); 1352 process_binary_op();
1349 break; 1353 break;
1350 1354
1351 case postfix_op: /* got a trailing ++ or -- */ 1355 case postfix_op: /* got a trailing ++ or -- */
1352 process_postfix_op(); 1356 process_postfix_op();
1353 break; 1357 break;
1354 1358
1355 case question: /* got a ? */ 1359 case question: /* got a ? */
1356 process_question(&squest); 1360 process_question(&squest);
1357 break; 1361 break;
1358 1362
1359 case case_label: /* got word 'case' or 'default' */ 1363 case case_label: /* got word 'case' or 'default' */
1360 scase = true; /* so we can process the later colon properly */ 1364 scase = true; /* so we can process the later colon properly */
1361 goto copy_id; 1365 goto copy_id;
1362 1366
1363 case colon: /* got a ':' */ 1367 case colon: /* got a ':' */
1364 process_colon(&squest, &force_nl, &scase); 1368 process_colon(&squest, &force_nl, &scase);
1365 break; 1369 break;
1366 1370
1367 case semicolon: /* got a ';' */ 1371 case semicolon: /* got a ';' */
1368 process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw, 1372 process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw,
1369 hd_type, &force_nl); 1373 hd_type, &force_nl);
1370 break; 1374 break;
1371 1375
1372 case lbrace: /* got a '{' */ 1376 case lbrace: /* got a '{' */
1373 process_lbrace(&force_nl, &sp_sw, hd_type, di_stack, 1377 process_lbrace(&force_nl, &sp_sw, hd_type, di_stack,
1374 nitems(di_stack), &dec_ind); 1378 nitems(di_stack), &dec_ind);
1375 break; 1379 break;
1376 1380
1377 case rbrace: /* got a '}' */ 1381 case rbrace: /* got a '}' */
1378 process_rbrace(&sp_sw, &dec_ind, di_stack); 1382 process_rbrace(&sp_sw, &dec_ind, di_stack);
1379 break; 1383 break;
1380 1384
1381 case switch_expr: /* got keyword "switch" */ 1385 case switch_expr: /* got keyword "switch" */
1382 sp_sw = true; 1386 sp_sw = true;
1383 hd_type = switch_expr; /* keep this for when we have seen the 1387 hd_type = switch_expr; /* keep this for when we have seen the
1384 * expression */ 1388 * expression */
1385 goto copy_id; /* go move the token into buffer */ 1389 goto copy_id; /* go move the token into buffer */
1386 1390
1387 case keyword_for_if_while: 1391 case keyword_for_if_while:
1388 sp_sw = true; /* the interesting stuff is done after the 1392 sp_sw = true; /* the interesting stuff is done after the
1389 * expression is scanned */ 1393 * expression is scanned */
1390 hd_type = (*token == 'i' ? if_expr : 1394 hd_type = (*token == 'i' ? if_expr :
1391 (*token == 'w' ? while_expr : for_exprs)); 1395 (*token == 'w' ? while_expr : for_exprs));
1392 1396
1393 /* remember the type of header for later use by parser */ 1397 /* remember the type of header for later use by parser */
1394 goto copy_id; /* copy the token into line */ 1398 goto copy_id; /* copy the token into line */
1395 1399
1396 case keyword_do_else: 1400 case keyword_do_else:
1397 process_keyword_do_else(&force_nl, &last_else); 1401 process_keyword_do_else(&force_nl, &last_else);
1398 goto copy_id; /* move the token into line */ 1402 goto copy_id; /* move the token into line */
1399 1403
1400 case type_def: 1404 case type_def:
1401 case storage_class: 1405 case storage_class:
1402 prefix_blankline_requested = 0; 1406 prefix_blankline_requested = 0;
1403 goto copy_id; 1407 goto copy_id;
1404 1408
1405 case keyword_struct_union_enum: 1409 case keyword_struct_union_enum:
1406 if (ps.p_l_follow > 0) 1410 if (ps.p_l_follow > 0)
1407 goto copy_id; 1411 goto copy_id;
1408 /* FALLTHROUGH */ 1412 /* FALLTHROUGH */
1409 case decl: /* we have a declaration type (int, etc.) */ 1413 case decl: /* we have a declaration type (int, etc.) */
1410 process_decl(&dec_ind, &tabs_to_var); 1414 process_decl(&dec_ind, &tabs_to_var);
1411 goto copy_id; 1415 goto copy_id;
1412 1416
1413 case funcname: 1417 case funcname:
1414 case ident: /* got an identifier or constant */ 1418 case ident: /* got an identifier or constant */
1415 process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl, 1419 process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl,
1416 hd_type); 1420 hd_type);
1417 copy_id: 1421 copy_id:
1418 copy_id(); 1422 copy_id();
1419 if (type_code != funcname) 1423 if (type_code != funcname)
1420 ps.want_blank = true; 1424 ps.want_blank = true;
1421 break; 1425 break;
1422 1426
1423 case string_prefix: 1427 case string_prefix:
1424 process_string_prefix(); 1428 process_string_prefix();
1425 break; 1429 break;
1426 1430
1427 case period: 1431 case period:
1428 process_period(); 1432 process_period();
1429 break; 1433 break;
1430 1434
1431 case comma: 1435 case comma:
1432 process_comma(dec_ind, tabs_to_var, &force_nl); 1436 process_comma(dec_ind, tabs_to_var, &force_nl);
1433 break; 1437 break;
1434 1438
1435 case preprocessing: /* '#' */ 1439 case preprocessing: /* '#' */
1436 process_preprocessing(); 1440 process_preprocessing();
1437 break; 1441 break;
1438 case comment: /* we have gotten a '/' followed by '*' */ 1442 case comment: /* we have gotten a '/' followed by '*' */
1439 pr_comment(); 1443 pr_comment();
1440 break; 1444 break;
1441 1445
1442 default: 1446 default:
1443 break; 1447 break;
1444 } /* end of big switch stmt */ 1448 } /* end of big switch stmt */
1445 1449
1446 *e_code = '\0'; /* make sure code section is null terminated */ 1450 *e_code = '\0'; /* make sure code section is null terminated */
1447 if (type_code != comment && 1451 if (type_code != comment &&
1448 type_code != newline && 1452 type_code != newline &&
1449 type_code != preprocessing) 1453 type_code != preprocessing)
1450 ps.last_token = type_code; 1454 ps.last_token = type_code;
1451 } 1455 }
1452} 1456}
1453 1457
1454int 1458int
1455main(int argc, char **argv) 1459main(int argc, char **argv)
1456{ 1460{
1457 main_init_globals(); 1461 main_init_globals();
1458 main_parse_command_line(argc, argv); 1462 main_parse_command_line(argc, argv);
1459#if HAVE_CAPSICUM 1463#if HAVE_CAPSICUM
1460 init_capsicum(); 1464 init_capsicum();
1461#endif 1465#endif
1462 main_prepare_parsing(); 1466 main_prepare_parsing();
1463 main_loop(); 1467 main_loop();
1464} 1468}
1465 1469
1466/* 1470/*
1467 * copy input file to backup file if in_name is /blah/blah/blah/file, then 1471 * copy input file to backup file if in_name is /blah/blah/blah/file, then
1468 * backup file will be ".Bfile" then make the backup file the input and 1472 * backup file will be ".Bfile" then make the backup file the input and
1469 * original input file the output 1473 * original input file the output
1470 */ 1474 */
1471static void 1475static void
1472bakcopy(void) 1476bakcopy(void)
1473{ 1477{
1474 int n, 1478 int n,
1475 bakchn; 1479 bakchn;
1476 char buff[8 * 1024]; 1480 char buff[8 * 1024];
1477 const char *p; 1481 const char *p;
1478 1482
1479 /* construct file name .Bfile */ 1483 /* construct file name .Bfile */
1480 for (p = in_name; *p; p++); /* skip to end of string */ 1484 for (p = in_name; *p; p++); /* skip to end of string */
1481 while (p > in_name && *p != '/') /* find last '/' */ 1485 while (p > in_name && *p != '/') /* find last '/' */
1482 p--; 1486 p--;
1483 if (*p == '/') 1487 if (*p == '/')
1484 p++; 1488 p++;
1485 sprintf(bakfile, "%s%s", p, simple_backup_suffix); 1489 sprintf(bakfile, "%s%s", p, simple_backup_suffix);
1486 1490
1487 /* copy in_name to backup file */ 1491 /* copy in_name to backup file */
1488 bakchn = creat(bakfile, 0600); 1492 bakchn = creat(bakfile, 0600);
1489 if (bakchn < 0) 1493 if (bakchn < 0)
1490 err(1, "%s", bakfile); 1494 err(1, "%s", bakfile);
1491 while ((n = read(fileno(input), buff, sizeof(buff))) > 0) 1495 while ((n = read(fileno(input), buff, sizeof(buff))) > 0)
1492 if (write(bakchn, buff, n) != n) 1496 if (write(bakchn, buff, n) != n)
1493 err(1, "%s", bakfile); 1497 err(1, "%s", bakfile);
1494 if (n < 0) 1498 if (n < 0)
1495 err(1, "%s", in_name); 1499 err(1, "%s", in_name);
1496 close(bakchn); 1500 close(bakchn);
1497 fclose(input); 1501 fclose(input);
1498 1502
1499 /* re-open backup file as the input file */ 1503 /* re-open backup file as the input file */
1500 input = fopen(bakfile, "r"); 1504 input = fopen(bakfile, "r");
1501 if (input == NULL) 1505 if (input == NULL)
1502 err(1, "%s", bakfile); 1506 err(1, "%s", bakfile);
1503 /* now the original input file will be the output */ 1507 /* now the original input file will be the output */
1504 output = fopen(in_name, "w"); 1508 output = fopen(in_name, "w");
1505 if (output == NULL) { 1509 if (output == NULL) {
1506 unlink(bakfile); 1510 unlink(bakfile);
1507 err(1, "%s", in_name); 1511 err(1, "%s", in_name);
1508 } 1512 }
1509} 1513}
1510 1514
1511static void 1515static void
1512indent_declaration(int cur_dec_ind, int tabs_to_var) 1516indent_declaration(int cur_dec_ind, int tabs_to_var)
1513{ 1517{
1514 int pos = e_code - s_code; 1518 int pos = e_code - s_code;
1515 char *startpos = e_code; 1519 char *startpos = e_code;
1516 1520
1517 /* 1521 /*
1518 * get the tab math right for indentations that are not multiples of tabsize 1522 * get the tab math right for indentations that are not multiples of tabsize
1519 */ 1523 */
1520 if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) { 1524 if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) {
1521 pos += (ps.ind_level * opt.ind_size) % opt.tabsize; 1525 pos += (ps.ind_level * opt.ind_size) % opt.tabsize;
1522 cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize; 1526 cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize;
1523 } 1527 }
1524 if (tabs_to_var) { 1528 if (tabs_to_var) {
1525 int tpos; 1529 int tpos;
1526 1530
1527 check_size_code(cur_dec_ind / opt.tabsize); 1531 check_size_code(cur_dec_ind / opt.tabsize);
1528 while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { 1532 while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) {
1529 *e_code++ = '\t'; 1533 *e_code++ = '\t';
1530 pos = tpos; 1534 pos = tpos;
1531 } 1535 }
1532 } 1536 }
1533 check_size_code(cur_dec_ind - pos + 1); 1537 check_size_code(cur_dec_ind - pos + 1);
1534 while (pos < cur_dec_ind) { 1538 while (pos < cur_dec_ind) {
1535 *e_code++ = ' '; 1539 *e_code++ = ' ';
1536 pos++; 1540 pos++;
1537 } 1541 }
1538 if (e_code == startpos && ps.want_blank) { 1542 if (e_code == startpos && ps.want_blank) {
1539 *e_code++ = ' '; 1543 *e_code++ = ' ';
1540 ps.want_blank = false; 1544 ps.want_blank = false;
1541 } 1545 }
1542} 1546}
1543 1547
1544#ifdef debug 1548#ifdef debug
1545void 1549void
1546debug_printf(const char *fmt, ...) 1550debug_printf(const char *fmt, ...)
1547{ 1551{
1548 FILE *f = output == stdout ? stderr : stdout; 1552 FILE *f = output == stdout ? stderr : stdout;
1549 va_list ap; 1553 va_list ap;
1550 1554
1551 va_start(ap, fmt); 1555 va_start(ap, fmt);
1552 vfprintf(f, fmt, ap); 1556 vfprintf(f, fmt, ap);
1553 va_end(ap); 1557 va_end(ap);
1554} 1558}
1555 1559
1556void 1560void
1557debug_println(const char *fmt, ...) 1561debug_println(const char *fmt, ...)
1558{ 1562{
1559 FILE *f = output == stdout ? stderr : stdout; 1563 FILE *f = output == stdout ? stderr : stdout;
1560 va_list ap; 1564 va_list ap;
1561 1565
1562 va_start(ap, fmt); 1566 va_start(ap, fmt);
1563 vfprintf(f, fmt, ap); 1567 vfprintf(f, fmt, ap);
1564 va_end(ap); 1568 va_end(ap);
1565 fprintf(f, "\n"); 1569 fprintf(f, "\n");
1566} 1570}
1567 1571
1568void 1572void
1569debug_vis_range(const char *prefix, const char *s, const char *e, 1573debug_vis_range(const char *prefix, const char *s, const char *e,
1570 const char *suffix) 1574 const char *suffix)
1571{ 1575{
1572 debug_printf("%s", prefix); 1576 debug_printf("%s", prefix);
1573 for (const char *p = s; p < e; p++) { 1577 for (const char *p = s; p < e; p++) {
1574 if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') 1578 if (isprint((unsigned char)*p) && *p != '\\' && *p != '"')
1575 debug_printf("%c", *p); 1579 debug_printf("%c", *p);
1576 else if (*p == '\n') 1580 else if (*p == '\n')
1577 debug_printf("\\n"); 1581 debug_printf("\\n");
1578 else if (*p == '\t') 1582 else if (*p == '\t')
1579 debug_printf("\\t"); 1583 debug_printf("\\t");
1580 else 1584 else
1581 debug_printf("\\x%02x", *p); 1585 debug_printf("\\x%02x", *p);
1582 } 1586 }
1583 debug_printf("%s", suffix); 1587 debug_printf("%s", suffix);
1584} 1588}
1585#endif 1589#endif