Tue Mar 9 19:23:08 2021 UTC ()
indent: rename a few more token types

The previous names were either too short or ambiguous.

No functional change.


(rillig)
diff -r1.38 -r1.39 src/usr.bin/indent/indent.c
diff -r1.10 -r1.11 src/usr.bin/indent/indent_codes.h
diff -r1.30 -r1.31 src/usr.bin/indent/lexi.c

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

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

cvs diff -r1.10 -r1.11 src/usr.bin/indent/Attic/indent_codes.h (switch to unified diff)

--- src/usr.bin/indent/Attic/indent_codes.h 2021/03/09 19:14:39 1.10
+++ src/usr.bin/indent/Attic/indent_codes.h 2021/03/09 19:23:08 1.11
@@ -1,82 +1,82 @@ @@ -1,82 +1,82 @@
1/* $NetBSD: indent_codes.h,v 1.10 2021/03/09 19:14:39 rillig Exp $ */ 1/* $NetBSD: indent_codes.h,v 1.11 2021/03/09 19:23:08 rillig Exp $ */
2 2
3/*- 3/*-
4 * SPDX-License-Identifier: BSD-4-Clause 4 * SPDX-License-Identifier: BSD-4-Clause
5 * 5 *
6 * Copyright (c) 1985 Sun Microsystems, Inc. 6 * Copyright (c) 1985 Sun Microsystems, Inc.
7 * Copyright (c) 1980, 1993 7 * Copyright (c) 1980, 1993
8 * The Regents of the University of California. All rights reserved. 8 * The Regents of the University of California. All rights reserved.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
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 * @(#)indent_codes.h 8.1 (Berkeley) 6/6/93 39 * @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
40 * $FreeBSD: head/usr.bin/indent/indent_codes.h 334564 2018-06-03 16:21:15Z pstef $ 40 * $FreeBSD: head/usr.bin/indent/indent_codes.h 334564 2018-06-03 16:21:15Z pstef $
41 */ 41 */
42 42
43typedef enum token_type { 43typedef enum token_type {
44 end_of_file, 44 end_of_file,
45 newline, 45 newline,
46 lparen, /* '(' or '[' */ 46 lparen, /* '(' or '[' */
47 rparen, /* ')' or ']' */ 47 rparen, /* ')' or ']' */
48 unary_op, /* e.g. '+' or '&' */ 48 unary_op, /* e.g. '+' or '&' */
49 binary_op, /* e.g. '<<' or '+' or '&&' or '/=' */ 49 binary_op, /* e.g. '<<' or '+' or '&&' or '/=' */
50 postop, /* trailing '++' or '--' */ 50 postfix_op, /* trailing '++' or '--' */
51 question, /* the '?' from a '?:' expression */ 51 question, /* the '?' from a '?:' expression */
52 case_label, 52 case_label,
53 colon, 53 colon,
54 semicolon, 54 semicolon,
55 lbrace, 55 lbrace,
56 rbrace, 56 rbrace,
57 ident, 57 ident,
58 comma, 58 comma,
59 comment, 59 comment,
60 switch_expr, /* 'switch' '(' <expr> ')' */ 60 switch_expr, /* 'switch' '(' <expr> ')' */
61 preesc, 61 preprocessing, /* '#' */
62 form_feed, 62 form_feed,
63 decl, 63 decl,
64 keyword_for_if_while, /* 'for', 'if' or 'while' */ 64 keyword_for_if_while, /* 'for', 'if' or 'while' */
65 keyword_do_else, /* 'do' or 'else' */ 65 keyword_do_else, /* 'do' or 'else' */
66 if_expr, /* 'if' '(' <expr> ')' */ 66 if_expr, /* 'if' '(' <expr> ')' */
67 while_expr, /* 'while' '(' <expr> ')' */ 67 while_expr, /* 'while' '(' <expr> ')' */
68 for_exprs, /* 'for' '(' ... ')' */ 68 for_exprs, /* 'for' '(' ... ')' */
69 stmt, 69 stmt,
70 stmt_list, 70 stmt_list,
71 keyword_else, /* 'else' */ 71 keyword_else, /* 'else' */
72 keyword_do, /* 'do' */ 72 keyword_do, /* 'do' */
73 do_stmt, /* 'do' <stmt> */ 73 do_stmt, /* 'do' <stmt> */
74 if_expr_stmt, /* 'if' '(' <expr> ')' <stmt> */ 74 if_expr_stmt, /* 'if' '(' <expr> ')' <stmt> */
75 if_expr_stmt_else, /* 'if' '(' <expr> ')' <stmt> 'else' */ 75 if_expr_stmt_else, /* 'if' '(' <expr> ')' <stmt> 'else' */
76 period, 76 period,
77 strpfx, 77 string_prefix, /* 'L' */
78 storage, 78 storage_class,
79 funcname, 79 funcname,
80 type_def, 80 type_def,
81 structure 81 keyword_struct_union_enum
82} token_type; 82} token_type;

cvs diff -r1.30 -r1.31 src/usr.bin/indent/lexi.c (switch to unified diff)

--- src/usr.bin/indent/lexi.c 2021/03/09 19:14:39 1.30
+++ src/usr.bin/indent/lexi.c 2021/03/09 19:23:08 1.31
@@ -1,734 +1,734 @@ @@ -1,734 +1,734 @@
1/* $NetBSD: lexi.c,v 1.30 2021/03/09 19:14:39 rillig Exp $ */ 1/* $NetBSD: lexi.c,v 1.31 2021/03/09 19:23:08 rillig Exp $ */
2 2
3/*- 3/*-
4 * SPDX-License-Identifier: BSD-4-Clause 4 * SPDX-License-Identifier: BSD-4-Clause
5 * 5 *
6 * Copyright (c) 1985 Sun Microsystems, Inc. 6 * Copyright (c) 1985 Sun Microsystems, Inc.
7 * Copyright (c) 1980, 1993 7 * Copyright (c) 1980, 1993
8 * The Regents of the University of California. All rights reserved. 8 * The Regents of the University of California. All rights reserved.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
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[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93"; 42static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/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: lexi.c,v 1.30 2021/03/09 19:14:39 rillig Exp $"); 49__RCSID("$NetBSD: lexi.c,v 1.31 2021/03/09 19:23:08 rillig Exp $");
50#elif defined(__FreeBSD__) 50#elif defined(__FreeBSD__)
51__FBSDID("$FreeBSD: head/usr.bin/indent/lexi.c 337862 2018-08-15 18:19:45Z pstef $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/lexi.c 337862 2018-08-15 18:19:45Z pstef $");
52#endif 52#endif
53#endif 53#endif
54 54
55/* 55/*
56 * Here we have the token scanner for indent. It scans off one token and puts 56 * Here we have the token scanner for indent. It scans off one token and puts
57 * it in the global variable "token". It returns a code, indicating the type 57 * it in the global variable "token". It returns a code, indicating the type
58 * of token scanned. 58 * of token scanned.
59 */ 59 */
60 60
61#include <assert.h> 61#include <assert.h>
62#include <err.h> 62#include <err.h>
63#include <stdio.h> 63#include <stdio.h>
64#include <ctype.h> 64#include <ctype.h>
65#include <stdlib.h> 65#include <stdlib.h>
66#include <string.h> 66#include <string.h>
67#include <sys/param.h> 67#include <sys/param.h>
68 68
69#include "indent.h" 69#include "indent.h"
70 70
71struct templ { 71struct templ {
72 const char *rwd; 72 const char *rwd;
73 enum rwcode rwcode; 73 enum rwcode rwcode;
74}; 74};
75 75
76/* 76/*
77 * This table has to be sorted alphabetically, because it'll be used in binary 77 * This table has to be sorted alphabetically, because it'll be used in binary
78 * search. 78 * search.
79 */ 79 */
80const struct templ specials[] = 80const struct templ specials[] =
81{ 81{
82 {"_Bool", rw_type}, 82 {"_Bool", rw_type},
83 {"_Complex", rw_type}, 83 {"_Complex", rw_type},
84 {"_Imaginary", rw_type}, 84 {"_Imaginary", rw_type},
85 {"auto", rw_storage_class}, 85 {"auto", rw_storage_class},
86 {"bool", rw_type}, 86 {"bool", rw_type},
87 {"break", rw_jump}, 87 {"break", rw_jump},
88 {"case", rw_case_or_default}, 88 {"case", rw_case_or_default},
89 {"char", rw_type}, 89 {"char", rw_type},
90 {"complex", rw_type}, 90 {"complex", rw_type},
91 {"const", rw_type}, 91 {"const", rw_type},
92 {"continue", rw_jump}, 92 {"continue", rw_jump},
93 {"default", rw_case_or_default}, 93 {"default", rw_case_or_default},
94 {"do", rw_do_or_else}, 94 {"do", rw_do_or_else},
95 {"double", rw_type}, 95 {"double", rw_type},
96 {"else", rw_do_or_else}, 96 {"else", rw_do_or_else},
97 {"enum", rw_struct_or_union_or_enum}, 97 {"enum", rw_struct_or_union_or_enum},
98 {"extern", rw_storage_class}, 98 {"extern", rw_storage_class},
99 {"float", rw_type}, 99 {"float", rw_type},
100 {"for", rw_for_or_if_or_while}, 100 {"for", rw_for_or_if_or_while},
101 {"global", rw_type}, 101 {"global", rw_type},
102 {"goto", rw_jump}, 102 {"goto", rw_jump},
103 {"if", rw_for_or_if_or_while}, 103 {"if", rw_for_or_if_or_while},
104 {"imaginary", rw_type}, 104 {"imaginary", rw_type},
105 {"inline", rw_inline_or_restrict}, 105 {"inline", rw_inline_or_restrict},
106 {"int", rw_type}, 106 {"int", rw_type},
107 {"long", rw_type}, 107 {"long", rw_type},
108 {"offsetof", rw_offsetof}, 108 {"offsetof", rw_offsetof},
109 {"register", rw_storage_class}, 109 {"register", rw_storage_class},
110 {"restrict", rw_inline_or_restrict}, 110 {"restrict", rw_inline_or_restrict},
111 {"return", rw_jump}, 111 {"return", rw_jump},
112 {"short", rw_type}, 112 {"short", rw_type},
113 {"signed", rw_type}, 113 {"signed", rw_type},
114 {"sizeof", rw_sizeof}, 114 {"sizeof", rw_sizeof},
115 {"static", rw_storage_class}, 115 {"static", rw_storage_class},
116 {"struct", rw_struct_or_union_or_enum}, 116 {"struct", rw_struct_or_union_or_enum},
117 {"switch", rw_switch}, 117 {"switch", rw_switch},
118 {"typedef", rw_typedef}, 118 {"typedef", rw_typedef},
119 {"union", rw_struct_or_union_or_enum}, 119 {"union", rw_struct_or_union_or_enum},
120 {"unsigned", rw_type}, 120 {"unsigned", rw_type},
121 {"void", rw_type}, 121 {"void", rw_type},
122 {"volatile", rw_type}, 122 {"volatile", rw_type},
123 {"while", rw_for_or_if_or_while} 123 {"while", rw_for_or_if_or_while}
124}; 124};
125 125
126const char **typenames; 126const char **typenames;
127int typename_count; 127int typename_count;
128int typename_top = -1; 128int typename_top = -1;
129 129
130/* 130/*
131 * The transition table below was rewritten by hand from lx's output, given 131 * The transition table below was rewritten by hand from lx's output, given
132 * the following definitions. lx is Katherine Flavel's lexer generator. 132 * the following definitions. lx is Katherine Flavel's lexer generator.
133 * 133 *
134 * O = /[0-7]/; D = /[0-9]/; NZ = /[1-9]/; 134 * O = /[0-7]/; D = /[0-9]/; NZ = /[1-9]/;
135 * H = /[a-f0-9]/i; B = /[0-1]/; HP = /0x/i; 135 * H = /[a-f0-9]/i; B = /[0-1]/; HP = /0x/i;
136 * BP = /0b/i; E = /e[+\-]?/i D+; P = /p[+\-]?/i D+; 136 * BP = /0b/i; E = /e[+\-]?/i D+; P = /p[+\-]?/i D+;
137 * FS = /[fl]/i; IS = /u/i /(l|L|ll|LL)/? | /(l|L|ll|LL)/ /u/i?; 137 * FS = /[fl]/i; IS = /u/i /(l|L|ll|LL)/? | /(l|L|ll|LL)/ /u/i?;
138 * 138 *
139 * D+ E FS? -> $float; 139 * D+ E FS? -> $float;
140 * D* "." D+ E? FS? -> $float; 140 * D* "." D+ E? FS? -> $float;
141 * D+ "." E? FS? -> $float; HP H+ IS? -> $int; 141 * D+ "." E? FS? -> $float; HP H+ IS? -> $int;
142 * HP H+ P FS? -> $float; NZ D* IS? -> $int; 142 * HP H+ P FS? -> $float; NZ D* IS? -> $int;
143 * HP H* "." H+ P FS? -> $float; "0" O* IS? -> $int; 143 * HP H* "." H+ P FS? -> $float; "0" O* IS? -> $int;
144 * HP H+ "." P FS -> $float; BP B+ IS? -> $int; 144 * HP H+ "." P FS -> $float; BP B+ IS? -> $int;
145 */ 145 */
146static char const *table[] = { 146static char const *table[] = {
147 /* examples: 147 /* examples:
148 00 148 00
149 s 0xx 149 s 0xx
150 t 00xaa 150 t 00xaa
151 a 11 101100xxa.. 151 a 11 101100xxa..
152 r 11ee0001101lbuuxx.a.pp 152 r 11ee0001101lbuuxx.a.pp
153 t.01.e+008bLuxll0Ll.aa.p+0 153 t.01.e+008bLuxll0Ll.aa.p+0
154 states: ABCDEFGHIJKLMNOPQRSTUVWXYZ */ 154 states: ABCDEFGHIJKLMNOPQRSTUVWXYZ */
155 ['0'] = "CEIDEHHHIJQ U Q VUVVZZZ", 155 ['0'] = "CEIDEHHHIJQ U Q VUVVZZZ",
156 ['1'] = "DEIDEHHHIJQ U Q VUVVZZZ", 156 ['1'] = "DEIDEHHHIJQ U Q VUVVZZZ",
157 ['7'] = "DEIDEHHHIJ U VUVVZZZ", 157 ['7'] = "DEIDEHHHIJ U VUVVZZZ",
158 ['9'] = "DEJDEHHHJJ U VUVVZZZ", 158 ['9'] = "DEJDEHHHJJ U VUVVZZZ",
159 ['a'] = " U VUVV ", 159 ['a'] = " U VUVV ",
160 ['b'] = " K U VUVV ", 160 ['b'] = " K U VUVV ",
161 ['e'] = " FFF FF U VUVV ", 161 ['e'] = " FFF FF U VUVV ",
162 ['f'] = " f f U VUVV f", 162 ['f'] = " f f U VUVV f",
163 ['u'] = " MM M i iiM M ", 163 ['u'] = " MM M i iiM M ",
164 ['x'] = " N ", 164 ['x'] = " N ",
165 ['p'] = " FFX ", 165 ['p'] = " FFX ",
166 ['L'] = " LLf fL PR Li L f", 166 ['L'] = " LLf fL PR Li L f",
167 ['l'] = " OOf fO S P O i O f", 167 ['l'] = " OOf fO S P O i O f",
168 ['+'] = " G Y ", 168 ['+'] = " G Y ",
169 ['.'] = "B EE EE T W ", 169 ['.'] = "B EE EE T W ",
170 /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */ 170 /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
171 [0] = "uuiifuufiuuiiuiiiiiuiuuuuu", 171 [0] = "uuiifuufiuuiiuiiiiiuiuuuuu",
172}; 172};
173 173
174static void 174static void
175check_size_token(size_t desired_size) 175check_size_token(size_t desired_size)
176{ 176{
177 if (e_token + (desired_size) >= l_token) { 177 if (e_token + (desired_size) >= l_token) {
178 int nsize = l_token - s_token + 400 + desired_size; 178 int nsize = l_token - s_token + 400 + desired_size;
179 int token_len = e_token - s_token; 179 int token_len = e_token - s_token;
180 tokenbuf = (char *)realloc(tokenbuf, nsize); 180 tokenbuf = (char *)realloc(tokenbuf, nsize);
181 if (tokenbuf == NULL) 181 if (tokenbuf == NULL)
182 err(1, NULL); 182 err(1, NULL);
183 e_token = tokenbuf + token_len + 1; 183 e_token = tokenbuf + token_len + 1;
184 l_token = tokenbuf + nsize - 5; 184 l_token = tokenbuf + nsize - 5;
185 s_token = tokenbuf + 1; 185 s_token = tokenbuf + 1;
186 } 186 }
187} 187}
188 188
189static int 189static int
190compare_templ_array(const void *key, const void *elem) 190compare_templ_array(const void *key, const void *elem)
191{ 191{
192 return strcmp(key, ((const struct templ *)elem)->rwd); 192 return strcmp(key, ((const struct templ *)elem)->rwd);
193} 193}
194 194
195static int 195static int
196compare_string_array(const void *key, const void *elem) 196compare_string_array(const void *key, const void *elem)
197{ 197{
198 return strcmp(key, *((const char *const *)elem)); 198 return strcmp(key, *((const char *const *)elem));
199} 199}
200 200
201#ifdef debug 201#ifdef debug
202const char * 202const char *
203token_type_name(token_type tk) 203token_type_name(token_type tk)
204{ 204{
205 static const char *const name[] = { 205 static const char *const name[] = {
206 "end_of_file", "newline", "lparen", "rparen", "unary_op", 206 "end_of_file", "newline", "lparen", "rparen", "unary_op",
207 "binary_op", "postop", "question", "case_label", "colon", 207 "binary_op", "postfix_op", "question", "case_label", "colon",
208 "semicolon", "lbrace", "rbrace", "ident", "comma", 208 "semicolon", "lbrace", "rbrace", "ident", "comma",
209 "comment", "switch_expr", "preesc", "form_feed", "decl", 209 "comment", "switch_expr", "preprocessing", "form_feed", "decl",
210 "keyword_for_if_while", "keyword_do_else", 210 "keyword_for_if_while", "keyword_do_else",
211 "if_expr", "while_expr", "for_exprs", 211 "if_expr", "while_expr", "for_exprs",
212 "stmt", "stmt_list", "keyword_else", "keyword_do", "do_stmt", 212 "stmt", "stmt_list", "keyword_else", "keyword_do", "do_stmt",
213 "if_expr_stmt", "if_expr_stmt_else", "period", "strpfx", "storage", 213 "if_expr_stmt", "if_expr_stmt_else", "period", "string_prefix",
214 "funcname", "type_def", "structure" 214 "storage_class", "funcname", "type_def", "keyword_struct_union_enum"
215 }; 215 };
216 216
217 assert(0 <= tk && tk < sizeof name / sizeof name[0]); 217 assert(0 <= tk && tk < sizeof name / sizeof name[0]);
218 218
219 return name[tk]; 219 return name[tk];
220} 220}
221 221
222static void 222static void
223print_buf(const char *name, const char *s, const char *e) 223print_buf(const char *name, const char *s, const char *e)
224{ 224{
225 if (s == e) 225 if (s == e)
226 return; 226 return;
227 227
228 printf(" %s \"", name); 228 printf(" %s \"", name);
229 for (const char *p = s; p < e; p++) { 229 for (const char *p = s; p < e; p++) {
230 if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') 230 if (isprint((unsigned char)*p) && *p != '\\' && *p != '"')
231 printf("%c", *p); 231 printf("%c", *p);
232 else if (*p == '\n') 232 else if (*p == '\n')
233 printf("\\n"); 233 printf("\\n");
234 else if (*p == '\t') 234 else if (*p == '\t')
235 printf("\\t"); 235 printf("\\t");
236 else 236 else
237 printf("\\x%02x", *p); 237 printf("\\x%02x", *p);
238 } 238 }
239 printf("\""); 239 printf("\"");
240} 240}
241 241
242static token_type 242static token_type
243lexi_end(token_type code) 243lexi_end(token_type code)
244{ 244{
245 printf("in line %d, lexi returns '%s'", line_no, token_type_name(code)); 245 printf("in line %d, lexi returns '%s'", line_no, token_type_name(code));
246 print_buf("token", s_token, e_token); 246 print_buf("token", s_token, e_token);
247 print_buf("label", s_lab, e_lab); 247 print_buf("label", s_lab, e_lab);
248 print_buf("code", s_code, e_code); 248 print_buf("code", s_code, e_code);
249 print_buf("comment", s_com, e_com); 249 print_buf("comment", s_com, e_com);
250 printf("\n"); 250 printf("\n");
251 251
252 return code; 252 return code;
253} 253}
254#else 254#else
255# define lexi_end(tk) (tk) 255# define lexi_end(tk) (tk)
256#endif 256#endif
257 257
258token_type 258token_type
259lexi(struct parser_state *state) 259lexi(struct parser_state *state)
260{ 260{
261 int unary_delim; /* this is set to 1 if the current token 261 int unary_delim; /* this is set to 1 if the current token
262 * forces a following operator to be unary */ 262 * forces a following operator to be unary */
263 token_type code; /* internal code to be returned */ 263 token_type code; /* internal code to be returned */
264 char qchar; /* the delimiter character for a string */ 264 char qchar; /* the delimiter character for a string */
265 265
266 e_token = s_token; /* point to start of place to save token */ 266 e_token = s_token; /* point to start of place to save token */
267 unary_delim = false; 267 unary_delim = false;
268 state->col_1 = state->last_nl; /* tell world that this token started 268 state->col_1 = state->last_nl; /* tell world that this token started
269 * in column 1 iff the last thing 269 * in column 1 iff the last thing
270 * scanned was a newline */ 270 * scanned was a newline */
271 state->last_nl = false; 271 state->last_nl = false;
272 272
273 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ 273 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
274 state->col_1 = false; /* leading blanks imply token is not in column 274 state->col_1 = false; /* leading blanks imply token is not in column
275 * 1 */ 275 * 1 */
276 if (++buf_ptr >= buf_end) 276 if (++buf_ptr >= buf_end)
277 fill_buffer(); 277 fill_buffer();
278 } 278 }
279 279
280 /* Scan an alphanumeric token */ 280 /* Scan an alphanumeric token */
281 if (isalnum((unsigned char)*buf_ptr) || 281 if (isalnum((unsigned char)*buf_ptr) ||
282 *buf_ptr == '_' || *buf_ptr == '$' || 282 *buf_ptr == '_' || *buf_ptr == '$' ||
283 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { 283 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
284 /* 284 /*
285 * we have a character or number 285 * we have a character or number
286 */ 286 */
287 struct templ *p; 287 struct templ *p;
288 288
289 if (isdigit((unsigned char)*buf_ptr) || 289 if (isdigit((unsigned char)*buf_ptr) ||
290 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { 290 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
291 char s; 291 char s;
292 unsigned char i; 292 unsigned char i;
293 293
294 for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) { 294 for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) {
295 i = (unsigned char)*buf_ptr; 295 i = (unsigned char)*buf_ptr;
296 if (i >= nitems(table) || table[i] == NULL || 296 if (i >= nitems(table) || table[i] == NULL ||
297 table[i][s - 'A'] == ' ') { 297 table[i][s - 'A'] == ' ') {
298 s = table[0][s - 'A']; 298 s = table[0][s - 'A'];
299 break; 299 break;
300 } 300 }
301 s = table[i][s - 'A']; 301 s = table[i][s - 'A'];
302 check_size_token(1); 302 check_size_token(1);
303 *e_token++ = *buf_ptr++; 303 *e_token++ = *buf_ptr++;
304 if (buf_ptr >= buf_end) 304 if (buf_ptr >= buf_end)
305 fill_buffer(); 305 fill_buffer();
306 } 306 }
307 /* s now indicates the type: f(loating), i(integer), u(nknown) */ 307 /* s now indicates the type: f(loating), i(integer), u(nknown) */
308 } 308 }
309 else 309 else
310 while (isalnum((unsigned char)*buf_ptr) || 310 while (isalnum((unsigned char)*buf_ptr) ||
311 *buf_ptr == '\\' || 311 *buf_ptr == '\\' ||
312 *buf_ptr == '_' || *buf_ptr == '$') { 312 *buf_ptr == '_' || *buf_ptr == '$') {
313 /* fill_buffer() terminates buffer with newline */ 313 /* fill_buffer() terminates buffer with newline */
314 if (*buf_ptr == '\\') { 314 if (*buf_ptr == '\\') {
315 if (*(buf_ptr + 1) == '\n') { 315 if (*(buf_ptr + 1) == '\n') {
316 buf_ptr += 2; 316 buf_ptr += 2;
317 if (buf_ptr >= buf_end) 317 if (buf_ptr >= buf_end)
318 fill_buffer(); 318 fill_buffer();
319 } else 319 } else
320 break; 320 break;
321 } 321 }
322 check_size_token(1); 322 check_size_token(1);
323 /* copy it over */ 323 /* copy it over */
324 *e_token++ = *buf_ptr++; 324 *e_token++ = *buf_ptr++;
325 if (buf_ptr >= buf_end) 325 if (buf_ptr >= buf_end)
326 fill_buffer(); 326 fill_buffer();
327 } 327 }
328 *e_token = '\0'; 328 *e_token = '\0';
329 329
330 if (s_token[0] == 'L' && s_token[1] == '\0' && 330 if (s_token[0] == 'L' && s_token[1] == '\0' &&
331 (*buf_ptr == '"' || *buf_ptr == '\'')) 331 (*buf_ptr == '"' || *buf_ptr == '\''))
332 return lexi_end(strpfx); 332 return lexi_end(string_prefix);
333 333
334 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ 334 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
335 if (++buf_ptr >= buf_end) 335 if (++buf_ptr >= buf_end)
336 fill_buffer(); 336 fill_buffer();
337 } 337 }
338 state->keyword = rw_0; 338 state->keyword = rw_0;
339 if (state->last_token == structure && !state->p_l_follow) { 339 if (state->last_token == keyword_struct_union_enum &&
340 /* if last token was 'struct' and we're not 340 !state->p_l_follow) {
341 * in parentheses, then this token 341 /* if last token was 'struct' and we're not in parentheses, then
342 * should be treated as a declaration */ 342 * this token should be treated as a declaration */
343 state->last_u_d = true; 343 state->last_u_d = true;
344 return lexi_end(decl); 344 return lexi_end(decl);
345 } 345 }
346 /* 346 /*
347 * Operator after identifier is binary unless last token was 'struct' 347 * Operator after identifier is binary unless last token was 'struct'
348 */ 348 */
349 state->last_u_d = (state->last_token == structure); 349 state->last_u_d = (state->last_token == keyword_struct_union_enum);
350 350
351 p = bsearch(s_token, specials, sizeof specials / sizeof specials[0], 351 p = bsearch(s_token, specials, sizeof specials / sizeof specials[0],
352 sizeof specials[0], compare_templ_array); 352 sizeof specials[0], compare_templ_array);
353 if (p == NULL) { /* not a special keyword... */ 353 if (p == NULL) { /* not a special keyword... */
354 char *u; 354 char *u;
355 355
356 /* ... so maybe a type_t or a typedef */ 356 /* ... so maybe a type_t or a typedef */
357 if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && 357 if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) &&
358 strcmp(u, "_t") == 0) || (typename_top >= 0 && 358 strcmp(u, "_t") == 0) || (typename_top >= 0 &&
359 bsearch(s_token, typenames, typename_top + 1, 359 bsearch(s_token, typenames, typename_top + 1,
360 sizeof typenames[0], compare_string_array))) { 360 sizeof typenames[0], compare_string_array))) {
361 state->keyword = rw_type; 361 state->keyword = rw_type;
362 state->last_u_d = true; 362 state->last_u_d = true;
363 goto found_typename; 363 goto found_typename;
364 } 364 }
365 } else { /* we have a keyword */ 365 } else { /* we have a keyword */
366 state->keyword = p->rwcode; 366 state->keyword = p->rwcode;
367 state->last_u_d = true; 367 state->last_u_d = true;
368 switch (p->rwcode) { 368 switch (p->rwcode) {
369 case rw_switch: 369 case rw_switch:
370 return lexi_end(switch_expr); 370 return lexi_end(switch_expr);
371 case rw_case_or_default: 371 case rw_case_or_default:
372 return lexi_end(case_label); 372 return lexi_end(case_label);
373 case rw_struct_or_union_or_enum: 373 case rw_struct_or_union_or_enum:
374 case rw_type: 374 case rw_type:
375 found_typename: 375 found_typename:
376 if (state->p_l_follow) { 376 if (state->p_l_follow) {
377 /* inside parens: cast, param list, offsetof or sizeof */ 377 /* inside parens: cast, param list, offsetof or sizeof */
378 state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; 378 state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask;
379 } 379 }
380 if (state->last_token == period || state->last_token == unary_op) { 380 if (state->last_token == period || state->last_token == unary_op) {
381 state->keyword = rw_0; 381 state->keyword = rw_0;
382 break; 382 break;
383 } 383 }
384 if (p != NULL && p->rwcode == rw_struct_or_union_or_enum) 384 if (p != NULL && p->rwcode == rw_struct_or_union_or_enum)
385 return lexi_end(structure); 385 return lexi_end(keyword_struct_union_enum);
386 if (state->p_l_follow) 386 if (state->p_l_follow)
387 break; 387 break;
388 return lexi_end(decl); 388 return lexi_end(decl);
389 389
390 case rw_for_or_if_or_while: 390 case rw_for_or_if_or_while:
391 return lexi_end(keyword_for_if_while); 391 return lexi_end(keyword_for_if_while);
392 392
393 case rw_do_or_else: 393 case rw_do_or_else:
394 return lexi_end(keyword_do_else); 394 return lexi_end(keyword_do_else);
395 395
396 case rw_storage_class: 396 case rw_storage_class:
397 return lexi_end(storage); 397 return lexi_end(storage_class);
398 398
399 case rw_typedef: 399 case rw_typedef:
400 return lexi_end(type_def); 400 return lexi_end(type_def);
401 401
402 default: /* all others are treated like any other 402 default: /* all others are treated like any other
403 * identifier */ 403 * identifier */
404 return lexi_end(ident); 404 return lexi_end(ident);
405 } /* end of switch */ 405 } /* end of switch */
406 } /* end of if (found_it) */ 406 } /* end of if (found_it) */
407 if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && 407 if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 &&
408 state->in_parameter_declaration == 0 && state->block_init == 0) { 408 state->in_parameter_declaration == 0 && state->block_init == 0) {
409 char *tp = buf_ptr; 409 char *tp = buf_ptr;
410 while (tp < buf_end) 410 while (tp < buf_end)
411 if (*tp++ == ')' && (*tp == ';' || *tp == ',')) 411 if (*tp++ == ')' && (*tp == ';' || *tp == ','))
412 goto not_proc; 412 goto not_proc;
413 strncpy(state->procname, token, sizeof state->procname - 1); 413 strncpy(state->procname, token, sizeof state->procname - 1);
414 if (state->in_decl) 414 if (state->in_decl)
415 state->in_parameter_declaration = 1; 415 state->in_parameter_declaration = 1;
416 return lexi_end(funcname); 416 return lexi_end(funcname);
417 not_proc:; 417 not_proc:;
418 } 418 }
419 /* 419 /*
420 * The following hack attempts to guess whether or not the current 420 * The following hack attempts to guess whether or not the current
421 * token is in fact a declaration keyword -- one that has been 421 * token is in fact a declaration keyword -- one that has been
422 * typedefd 422 * typedefd
423 */ 423 */
424 else if (!state->p_l_follow && !state->block_init && 424 else if (!state->p_l_follow && !state->block_init &&
425 !state->in_stmt && 425 !state->in_stmt &&
426 ((*buf_ptr == '*' && buf_ptr[1] != '=') || 426 ((*buf_ptr == '*' && buf_ptr[1] != '=') ||
427 isalpha((unsigned char)*buf_ptr)) && 427 isalpha((unsigned char)*buf_ptr)) &&
428 (state->last_token == semicolon || state->last_token == lbrace || 428 (state->last_token == semicolon || state->last_token == lbrace ||
429 state->last_token == rbrace)) { 429 state->last_token == rbrace)) {
430 state->keyword = rw_type; 430 state->keyword = rw_type;
431 state->last_u_d = true; 431 state->last_u_d = true;
432 return lexi_end(decl); 432 return lexi_end(decl);
433 } 433 }
434 if (state->last_token == decl) /* if this is a declared variable, 434 if (state->last_token == decl) /* if this is a declared variable,
435 * then following sign is unary */ 435 * then following sign is unary */
436 state->last_u_d = true; /* will make "int a -1" work */ 436 state->last_u_d = true; /* will make "int a -1" work */
437 return lexi_end(ident); /* the ident is not in the list */ 437 return lexi_end(ident); /* the ident is not in the list */
438 } /* end of procesing for alpanum character */ 438 } /* end of procesing for alpanum character */
439 439
440 /* Scan a non-alphanumeric token */ 440 /* Scan a non-alphanumeric token */
441 441
442 check_size_token(3); /* things like "<<=" */ 442 check_size_token(3); /* things like "<<=" */
443 *e_token++ = *buf_ptr; /* if it is only a one-character token, it is 443 *e_token++ = *buf_ptr; /* if it is only a one-character token, it is
444 * moved here */ 444 * moved here */
445 *e_token = '\0'; 445 *e_token = '\0';
446 if (++buf_ptr >= buf_end) 446 if (++buf_ptr >= buf_end)
447 fill_buffer(); 447 fill_buffer();
448 448
449 switch (*token) { 449 switch (*token) {
450 case '\n': 450 case '\n':
451 unary_delim = state->last_u_d; 451 unary_delim = state->last_u_d;
452 state->last_nl = true; /* remember that we just had a newline */ 452 state->last_nl = true; /* remember that we just had a newline */
453 code = (had_eof ? end_of_file : newline); 453 code = (had_eof ? end_of_file : newline);
454 454
455 /* 455 /*
456 * if data has been exhausted, the newline is a dummy, and we should 456 * if data has been exhausted, the newline is a dummy, and we should
457 * return code to stop 457 * return code to stop
458 */ 458 */
459 break; 459 break;
460 460
461 case '\'': /* start of quoted character */ 461 case '\'': /* start of quoted character */
462 case '"': /* start of string */ 462 case '"': /* start of string */
463 qchar = *token; 463 qchar = *token;
464 do { /* copy the string */ 464 do { /* copy the string */
465 while (1) { /* move one character or [/<char>]<char> */ 465 while (1) { /* move one character or [/<char>]<char> */
466 if (*buf_ptr == '\n') { 466 if (*buf_ptr == '\n') {
467 diag(1, "Unterminated literal"); 467 diag(1, "Unterminated literal");
468 goto stop_lit; 468 goto stop_lit;
469 } 469 }
470 check_size_token(2); 470 check_size_token(2);
471 *e_token = *buf_ptr++; 471 *e_token = *buf_ptr++;
472 if (buf_ptr >= buf_end) 472 if (buf_ptr >= buf_end)
473 fill_buffer(); 473 fill_buffer();
474 if (*e_token == '\\') { /* if escape, copy extra char */ 474 if (*e_token == '\\') { /* if escape, copy extra char */
475 if (*buf_ptr == '\n') /* check for escaped newline */ 475 if (*buf_ptr == '\n') /* check for escaped newline */
476 ++line_no; 476 ++line_no;
477 *++e_token = *buf_ptr++; 477 *++e_token = *buf_ptr++;
478 ++e_token; /* we must increment this again because we 478 ++e_token; /* we must increment this again because we
479 * copied two chars */ 479 * copied two chars */
480 if (buf_ptr >= buf_end) 480 if (buf_ptr >= buf_end)
481 fill_buffer(); 481 fill_buffer();
482 } 482 }
483 else 483 else
484 break; /* we copied one character */ 484 break; /* we copied one character */
485 } /* end of while (1) */ 485 } /* end of while (1) */
486 } while (*e_token++ != qchar); 486 } while (*e_token++ != qchar);
487stop_lit: 487stop_lit:
488 code = ident; 488 code = ident;
489 break; 489 break;
490 490
491 case ('('): 491 case ('('):
492 case ('['): 492 case ('['):
493 unary_delim = true; 493 unary_delim = true;
494 code = lparen; 494 code = lparen;
495 break; 495 break;
496 496
497 case (')'): 497 case (')'):
498 case (']'): 498 case (']'):
499 code = rparen; 499 code = rparen;
500 break; 500 break;
501 501
502 case '#': 502 case '#':
503 unary_delim = state->last_u_d; 503 unary_delim = state->last_u_d;
504 code = preesc; 504 code = preprocessing;
505 break; 505 break;
506 506
507 case '?': 507 case '?':
508 unary_delim = true; 508 unary_delim = true;
509 code = question; 509 code = question;
510 break; 510 break;
511 511
512 case (':'): 512 case (':'):
513 code = colon; 513 code = colon;
514 unary_delim = true; 514 unary_delim = true;
515 break; 515 break;
516 516
517 case (';'): 517 case (';'):
518 unary_delim = true; 518 unary_delim = true;
519 code = semicolon; 519 code = semicolon;
520 break; 520 break;
521 521
522 case ('{'): 522 case ('{'):
523 unary_delim = true; 523 unary_delim = true;
524 524
525 /* 525 /*
526 * if (state->in_or_st) state->block_init = 1; 526 * if (state->in_or_st) state->block_init = 1;
527 */ 527 */
528 /* ? code = state->block_init ? lparen : lbrace; */ 528 /* ? code = state->block_init ? lparen : lbrace; */
529 code = lbrace; 529 code = lbrace;
530 break; 530 break;
531 531
532 case ('}'): 532 case ('}'):
533 unary_delim = true; 533 unary_delim = true;
534 /* ? code = state->block_init ? rparen : rbrace; */ 534 /* ? code = state->block_init ? rparen : rbrace; */
535 code = rbrace; 535 code = rbrace;
536 break; 536 break;
537 537
538 case 014: /* a form feed */ 538 case 014: /* a form feed */
539 unary_delim = state->last_u_d; 539 unary_delim = state->last_u_d;
540 state->last_nl = true; /* remember this so we can set 'state->col_1' 540 state->last_nl = true; /* remember this so we can set 'state->col_1'
541 * right */ 541 * right */
542 code = form_feed; 542 code = form_feed;
543 break; 543 break;
544 544
545 case (','): 545 case (','):
546 unary_delim = true; 546 unary_delim = true;
547 code = comma; 547 code = comma;
548 break; 548 break;
549 549
550 case '.': 550 case '.':
551 unary_delim = false; 551 unary_delim = false;
552 code = period; 552 code = period;
553 break; 553 break;
554 554
555 case '-': 555 case '-':
556 case '+': /* check for -, +, --, ++ */ 556 case '+': /* check for -, +, --, ++ */
557 code = (state->last_u_d ? unary_op : binary_op); 557 code = (state->last_u_d ? unary_op : binary_op);
558 unary_delim = true; 558 unary_delim = true;
559 559
560 if (*buf_ptr == token[0]) { 560 if (*buf_ptr == token[0]) {
561 /* check for doubled character */ 561 /* check for doubled character */
562 *e_token++ = *buf_ptr++; 562 *e_token++ = *buf_ptr++;
563 /* buffer overflow will be checked at end of loop */ 563 /* buffer overflow will be checked at end of loop */
564 if (state->last_token == ident || state->last_token == rparen) { 564 if (state->last_token == ident || state->last_token == rparen) {
565 code = (state->last_u_d ? unary_op : postop); 565 code = (state->last_u_d ? unary_op : postfix_op);
566 /* check for following ++ or -- */ 566 /* check for following ++ or -- */
567 unary_delim = false; 567 unary_delim = false;
568 } 568 }
569 } 569 }
570 else if (*buf_ptr == '=') 570 else if (*buf_ptr == '=')
571 /* check for operator += */ 571 /* check for operator += */
572 *e_token++ = *buf_ptr++; 572 *e_token++ = *buf_ptr++;
573 else if (*buf_ptr == '>') { 573 else if (*buf_ptr == '>') {
574 /* check for operator -> */ 574 /* check for operator -> */
575 *e_token++ = *buf_ptr++; 575 *e_token++ = *buf_ptr++;
576 unary_delim = false; 576 unary_delim = false;
577 code = unary_op; 577 code = unary_op;
578 state->want_blank = false; 578 state->want_blank = false;
579 } 579 }
580 break; /* buffer overflow will be checked at end of 580 break; /* buffer overflow will be checked at end of
581 * switch */ 581 * switch */
582 582
583 case '=': 583 case '=':
584 if (state->in_or_st) 584 if (state->in_or_st)
585 state->block_init = 1; 585 state->block_init = 1;
586 if (*buf_ptr == '=') { /* == */ 586 if (*buf_ptr == '=') { /* == */
587 *e_token++ = '='; /* Flip =+ to += */ 587 *e_token++ = '='; /* Flip =+ to += */
588 buf_ptr++; 588 buf_ptr++;
589 *e_token = 0; 589 *e_token = 0;
590 } 590 }
591 code = binary_op; 591 code = binary_op;
592 unary_delim = true; 592 unary_delim = true;
593 break; 593 break;
594 /* can drop thru!!! */ 594 /* can drop thru!!! */
595 595
596 case '>': 596 case '>':
597 case '<': 597 case '<':
598 case '!': /* ops like <, <<, <=, !=, etc */ 598 case '!': /* ops like <, <<, <=, !=, etc */
599 if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') { 599 if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
600 *e_token++ = *buf_ptr; 600 *e_token++ = *buf_ptr;
601 if (++buf_ptr >= buf_end) 601 if (++buf_ptr >= buf_end)
602 fill_buffer(); 602 fill_buffer();
603 } 603 }
604 if (*buf_ptr == '=') 604 if (*buf_ptr == '=')
605 *e_token++ = *buf_ptr++; 605 *e_token++ = *buf_ptr++;
606 code = (state->last_u_d ? unary_op : binary_op); 606 code = (state->last_u_d ? unary_op : binary_op);
607 unary_delim = true; 607 unary_delim = true;
608 break; 608 break;
609 609
610 case '*': 610 case '*':
611 unary_delim = true; 611 unary_delim = true;
612 if (!state->last_u_d) { 612 if (!state->last_u_d) {
613 if (*buf_ptr == '=') 613 if (*buf_ptr == '=')
614 *e_token++ = *buf_ptr++; 614 *e_token++ = *buf_ptr++;
615 code = binary_op; 615 code = binary_op;
616 break; 616 break;
617 } 617 }
618 while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { 618 while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) {
619 if (*buf_ptr == '*') { 619 if (*buf_ptr == '*') {
620 check_size_token(1); 620 check_size_token(1);
621 *e_token++ = *buf_ptr; 621 *e_token++ = *buf_ptr;
622 } 622 }
623 if (++buf_ptr >= buf_end) 623 if (++buf_ptr >= buf_end)
624 fill_buffer(); 624 fill_buffer();
625 } 625 }
626 if (ps.in_decl) { 626 if (ps.in_decl) {
627 char *tp = buf_ptr; 627 char *tp = buf_ptr;
628 628
629 while (isalpha((unsigned char)*tp) || 629 while (isalpha((unsigned char)*tp) ||
630 isspace((unsigned char)*tp)) { 630 isspace((unsigned char)*tp)) {
631 if (++tp >= buf_end) 631 if (++tp >= buf_end)
632 fill_buffer(); 632 fill_buffer();
633 } 633 }
634 if (*tp == '(') 634 if (*tp == '(')
635 ps.procname[0] = ' '; 635 ps.procname[0] = ' ';
636 } 636 }
637 code = unary_op; 637 code = unary_op;
638 break; 638 break;
639 639
640 default: 640 default:
641 if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { 641 if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) {
642 /* it is start of comment */ 642 /* it is start of comment */
643 *e_token++ = *buf_ptr; 643 *e_token++ = *buf_ptr;
644 644
645 if (++buf_ptr >= buf_end) 645 if (++buf_ptr >= buf_end)
646 fill_buffer(); 646 fill_buffer();
647 647
648 code = comment; 648 code = comment;
649 unary_delim = state->last_u_d; 649 unary_delim = state->last_u_d;
650 break; 650 break;
651 } 651 }
652 while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') { 652 while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') {
653 /* 653 /*
654 * handle ||, &&, etc, and also things as in int *****i 654 * handle ||, &&, etc, and also things as in int *****i
655 */ 655 */
656 check_size_token(1); 656 check_size_token(1);
657 *e_token++ = *buf_ptr; 657 *e_token++ = *buf_ptr;
658 if (++buf_ptr >= buf_end) 658 if (++buf_ptr >= buf_end)
659 fill_buffer(); 659 fill_buffer();
660 } 660 }
661 code = (state->last_u_d ? unary_op : binary_op); 661 code = (state->last_u_d ? unary_op : binary_op);
662 unary_delim = true; 662 unary_delim = true;
663 663
664 664
665 } /* end of switch */ 665 } /* end of switch */
666 if (buf_ptr >= buf_end) /* check for input buffer empty */ 666 if (buf_ptr >= buf_end) /* check for input buffer empty */
667 fill_buffer(); 667 fill_buffer();
668 state->last_u_d = unary_delim; 668 state->last_u_d = unary_delim;
669 check_size_token(1); 669 check_size_token(1);
670 *e_token = '\0'; /* null terminate the token */ 670 *e_token = '\0'; /* null terminate the token */
671 return lexi_end(code); 671 return lexi_end(code);
672} 672}
673 673
674/* Initialize constant transition table */ 674/* Initialize constant transition table */
675void 675void
676init_constant_tt(void) 676init_constant_tt(void)
677{ 677{
678 table['-'] = table['+']; 678 table['-'] = table['+'];
679 table['8'] = table['9']; 679 table['8'] = table['9'];
680 table['2'] = table['3'] = table['4'] = table['5'] = table['6'] = table['7']; 680 table['2'] = table['3'] = table['4'] = table['5'] = table['6'] = table['7'];
681 table['A'] = table['C'] = table['D'] = table['c'] = table['d'] = table['a']; 681 table['A'] = table['C'] = table['D'] = table['c'] = table['d'] = table['a'];
682 table['B'] = table['b']; 682 table['B'] = table['b'];
683 table['E'] = table['e']; 683 table['E'] = table['e'];
684 table['U'] = table['u']; 684 table['U'] = table['u'];
685 table['X'] = table['x']; 685 table['X'] = table['x'];
686 table['P'] = table['p']; 686 table['P'] = table['p'];
687 table['F'] = table['f']; 687 table['F'] = table['f'];
688} 688}
689 689
690void 690void
691alloc_typenames(void) 691alloc_typenames(void)
692{ 692{
693 693
694 typenames = (const char **)malloc(sizeof(typenames[0]) * 694 typenames = (const char **)malloc(sizeof(typenames[0]) *
695 (typename_count = 16)); 695 (typename_count = 16));
696 if (typenames == NULL) 696 if (typenames == NULL)
697 err(1, NULL); 697 err(1, NULL);
698} 698}
699 699
700void 700void
701add_typename(const char *key) 701add_typename(const char *key)
702{ 702{
703 int comparison; 703 int comparison;
704 const char *copy; 704 const char *copy;
705 705
706 if (typename_top + 1 >= typename_count) { 706 if (typename_top + 1 >= typename_count) {
707 typenames = realloc((void *)typenames, 707 typenames = realloc((void *)typenames,
708 sizeof(typenames[0]) * (typename_count *= 2)); 708 sizeof(typenames[0]) * (typename_count *= 2));
709 if (typenames == NULL) 709 if (typenames == NULL)
710 err(1, NULL); 710 err(1, NULL);
711 } 711 }
712 if (typename_top == -1) 712 if (typename_top == -1)
713 typenames[++typename_top] = copy = strdup(key); 713 typenames[++typename_top] = copy = strdup(key);
714 else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { 714 else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) {
715 /* take advantage of sorted input */ 715 /* take advantage of sorted input */
716 if (comparison == 0) /* remove duplicates */ 716 if (comparison == 0) /* remove duplicates */
717 return; 717 return;
718 typenames[++typename_top] = copy = strdup(key); 718 typenames[++typename_top] = copy = strdup(key);
719 } 719 }
720 else { 720 else {
721 int p; 721 int p;
722 722
723 for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) 723 for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++)
724 /* find place for the new key */; 724 /* find place for the new key */;
725 if (comparison == 0) /* remove duplicates */ 725 if (comparison == 0) /* remove duplicates */
726 return; 726 return;
727 memmove(&typenames[p + 1], &typenames[p], 727 memmove(&typenames[p + 1], &typenames[p],
728 sizeof(typenames[0]) * (++typename_top - p)); 728 sizeof(typenames[0]) * (++typename_top - p));
729 typenames[p] = copy = strdup(key); 729 typenames[p] = copy = strdup(key);
730 } 730 }
731 731
732 if (copy == NULL) 732 if (copy == NULL)
733 err(1, NULL); 733 err(1, NULL);
734} 734}