Fri Mar 12 23:10:18 2021 UTC ()
indent: use consistent indentation for 'else'

Half of the code used -ce, the other half the opposite -nce.

No functional change.


(rillig)
diff -r1.18 -r1.19 src/usr.bin/indent/args.c
diff -r1.18 -r1.19 src/usr.bin/indent/pr_comment.c
diff -r1.44 -r1.45 src/usr.bin/indent/indent.c
diff -r1.29 -r1.30 src/usr.bin/indent/io.c
diff -r1.37 -r1.38 src/usr.bin/indent/lexi.c
diff -r1.17 -r1.18 src/usr.bin/indent/parse.c

cvs diff -r1.18 -r1.19 src/usr.bin/indent/args.c (switch to unified diff)

--- src/usr.bin/indent/args.c 2021/03/09 16:48:28 1.18
+++ src/usr.bin/indent/args.c 2021/03/12 23:10:18 1.19
@@ -1,360 +1,359 @@ @@ -1,360 +1,359 @@
1/* $NetBSD: args.c,v 1.18 2021/03/09 16:48:28 rillig Exp $ */ 1/* $NetBSD: args.c,v 1.19 2021/03/12 23:10:18 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[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; 42static char sccsid[] = "@(#)args.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: args.c,v 1.18 2021/03/09 16:48:28 rillig Exp $"); 49__RCSID("$NetBSD: args.c,v 1.19 2021/03/12 23:10:18 rillig Exp $");
50#elif defined(__FreeBSD__) 50#elif defined(__FreeBSD__)
51__FBSDID("$FreeBSD: head/usr.bin/indent/args.c 336318 2018-07-15 21:04:21Z pstef $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/args.c 336318 2018-07-15 21:04:21Z pstef $");
52#endif 52#endif
53#endif 53#endif
54 54
55/* 55/*
56 * Argument scanning and profile reading code. Default parameters are set 56 * Argument scanning and profile reading code. Default parameters are set
57 * here as well. 57 * here as well.
58 */ 58 */
59 59
60#include <ctype.h> 60#include <ctype.h>
61#include <err.h> 61#include <err.h>
62#include <limits.h> 62#include <limits.h>
63#include <stdio.h> 63#include <stdio.h>
64#include <stdlib.h> 64#include <stdlib.h>
65#include <string.h> 65#include <string.h>
66 66
67#include "indent.h" 67#include "indent.h"
68 68
69#define INDENT_VERSION "2.0" 69#define INDENT_VERSION "2.0"
70 70
71/* profile types */ 71/* profile types */
72#define PRO_SPECIAL 1 /* special case */ 72#define PRO_SPECIAL 1 /* special case */
73#define PRO_BOOL 2 /* boolean */ 73#define PRO_BOOL 2 /* boolean */
74#define PRO_INT 3 /* integer */ 74#define PRO_INT 3 /* integer */
75 75
76/* profile specials for booleans */ 76/* profile specials for booleans */
77#define ON 1 /* turn it on */ 77#define ON 1 /* turn it on */
78#define OFF 0 /* turn it off */ 78#define OFF 0 /* turn it off */
79 79
80/* profile specials for specials */ 80/* profile specials for specials */
81#define IGN 1 /* ignore it */ 81#define IGN 1 /* ignore it */
82#define CLI 2 /* case label indent (float) */ 82#define CLI 2 /* case label indent (float) */
83#define STDIN 3 /* use stdin */ 83#define STDIN 3 /* use stdin */
84#define KEY 4 /* type (keyword) */ 84#define KEY 4 /* type (keyword) */
85 85
86static void scan_profile(FILE *); 86static void scan_profile(FILE *);
87 87
88#define KEY_FILE 5 /* only used for args */ 88#define KEY_FILE 5 /* only used for args */
89#define VERSION 6 /* only used for args */ 89#define VERSION 6 /* only used for args */
90 90
91const char *option_source = "?"; 91const char *option_source = "?";
92 92
93void add_typedefs_from_file(const char *str); 93void add_typedefs_from_file(const char *str);
94 94
95/* 95/*
96 * N.B.: because of the way the table here is scanned, options whose names are 96 * N.B.: because of the way the table here is scanned, options whose names are
97 * substrings of other options must occur later; that is, with -lp vs -l, -lp 97 * substrings of other options must occur later; that is, with -lp vs -l, -lp
98 * must be first. Also, while (most) booleans occur more than once, the last 98 * must be first. Also, while (most) booleans occur more than once, the last
99 * default value is the one actually assigned. 99 * default value is the one actually assigned.
100 */ 100 */
101const struct pro { 101const struct pro {
102 const char *p_name; /* name, e.g. -bl, -cli */ 102 const char *p_name; /* name, e.g. -bl, -cli */
103 int p_type; /* type (int, bool, special) */ 103 int p_type; /* type (int, bool, special) */
104 int p_default; /* the default value (if int) */ 104 int p_default; /* the default value (if int) */
105 int p_special; /* depends on type */ 105 int p_special; /* depends on type */
106 int *p_obj; /* the associated variable */ 106 int *p_obj; /* the associated variable */
107} pro[] = { 107} pro[] = {
108 {"T", PRO_SPECIAL, 0, KEY, 0}, 108 {"T", PRO_SPECIAL, 0, KEY, 0},
109 {"U", PRO_SPECIAL, 0, KEY_FILE, 0}, 109 {"U", PRO_SPECIAL, 0, KEY_FILE, 0},
110 {"-version", PRO_SPECIAL, 0, VERSION, 0}, 110 {"-version", PRO_SPECIAL, 0, VERSION, 0},
111 {"P", PRO_SPECIAL, 0, IGN, 0}, 111 {"P", PRO_SPECIAL, 0, IGN, 0},
112 {"bacc", PRO_BOOL, false, ON, &opt.blanklines_around_conditional_compilation}, 112 {"bacc", PRO_BOOL, false, ON, &opt.blanklines_around_conditional_compilation},
113 {"badp", PRO_BOOL, false, ON, &opt.blanklines_after_declarations_at_proctop}, 113 {"badp", PRO_BOOL, false, ON, &opt.blanklines_after_declarations_at_proctop},
114 {"bad", PRO_BOOL, false, ON, &opt.blanklines_after_declarations}, 114 {"bad", PRO_BOOL, false, ON, &opt.blanklines_after_declarations},
115 {"bap", PRO_BOOL, false, ON, &opt.blanklines_after_procs}, 115 {"bap", PRO_BOOL, false, ON, &opt.blanklines_after_procs},
116 {"bbb", PRO_BOOL, false, ON, &opt.blanklines_before_blockcomments}, 116 {"bbb", PRO_BOOL, false, ON, &opt.blanklines_before_blockcomments},
117 {"bc", PRO_BOOL, true, OFF, &opt.leave_comma}, 117 {"bc", PRO_BOOL, true, OFF, &opt.leave_comma},
118 {"bl", PRO_BOOL, true, OFF, &opt.btype_2}, 118 {"bl", PRO_BOOL, true, OFF, &opt.btype_2},
119 {"br", PRO_BOOL, true, ON, &opt.btype_2}, 119 {"br", PRO_BOOL, true, ON, &opt.btype_2},
120 {"bs", PRO_BOOL, false, ON, &opt.Bill_Shannon}, 120 {"bs", PRO_BOOL, false, ON, &opt.Bill_Shannon},
121 {"cdb", PRO_BOOL, true, ON, &opt.comment_delimiter_on_blankline}, 121 {"cdb", PRO_BOOL, true, ON, &opt.comment_delimiter_on_blankline},
122 {"cd", PRO_INT, 0, 0, &opt.decl_com_ind}, 122 {"cd", PRO_INT, 0, 0, &opt.decl_com_ind},
123 {"ce", PRO_BOOL, true, ON, &opt.cuddle_else}, 123 {"ce", PRO_BOOL, true, ON, &opt.cuddle_else},
124 {"ci", PRO_INT, 0, 0, &opt.continuation_indent}, 124 {"ci", PRO_INT, 0, 0, &opt.continuation_indent},
125 {"cli", PRO_SPECIAL, 0, CLI, 0}, 125 {"cli", PRO_SPECIAL, 0, CLI, 0},
126 {"cs", PRO_BOOL, false, ON, &opt.space_after_cast}, 126 {"cs", PRO_BOOL, false, ON, &opt.space_after_cast},
127 {"c", PRO_INT, 33, 0, &opt.com_ind}, 127 {"c", PRO_INT, 33, 0, &opt.com_ind},
128 {"di", PRO_INT, 16, 0, &opt.decl_indent}, 128 {"di", PRO_INT, 16, 0, &opt.decl_indent},
129 {"dj", PRO_BOOL, false, ON, &opt.ljust_decl}, 129 {"dj", PRO_BOOL, false, ON, &opt.ljust_decl},
130 {"d", PRO_INT, 0, 0, &opt.unindent_displace}, 130 {"d", PRO_INT, 0, 0, &opt.unindent_displace},
131 {"eei", PRO_BOOL, false, ON, &opt.extra_expression_indent}, 131 {"eei", PRO_BOOL, false, ON, &opt.extra_expression_indent},
132 {"ei", PRO_BOOL, true, ON, &opt.else_if}, 132 {"ei", PRO_BOOL, true, ON, &opt.else_if},
133 {"fbs", PRO_BOOL, true, ON, &opt.function_brace_split}, 133 {"fbs", PRO_BOOL, true, ON, &opt.function_brace_split},
134 {"fc1", PRO_BOOL, true, ON, &opt.format_col1_comments}, 134 {"fc1", PRO_BOOL, true, ON, &opt.format_col1_comments},
135 {"fcb", PRO_BOOL, true, ON, &opt.format_block_comments}, 135 {"fcb", PRO_BOOL, true, ON, &opt.format_block_comments},
136 {"ip", PRO_BOOL, true, ON, &opt.indent_parameters}, 136 {"ip", PRO_BOOL, true, ON, &opt.indent_parameters},
137 {"i", PRO_INT, 8, 0, &opt.ind_size}, 137 {"i", PRO_INT, 8, 0, &opt.ind_size},
138 {"lc", PRO_INT, 0, 0, &opt.block_comment_max_col}, 138 {"lc", PRO_INT, 0, 0, &opt.block_comment_max_col},
139 {"ldi", PRO_INT, -1, 0, &opt.local_decl_indent}, 139 {"ldi", PRO_INT, -1, 0, &opt.local_decl_indent},
140 {"lpl", PRO_BOOL, false, ON, &opt.lineup_to_parens_always}, 140 {"lpl", PRO_BOOL, false, ON, &opt.lineup_to_parens_always},
141 {"lp", PRO_BOOL, true, ON, &opt.lineup_to_parens}, 141 {"lp", PRO_BOOL, true, ON, &opt.lineup_to_parens},
142 {"l", PRO_INT, 78, 0, &opt.max_col}, 142 {"l", PRO_INT, 78, 0, &opt.max_col},
143 {"nbacc", PRO_BOOL, false, OFF, &opt.blanklines_around_conditional_compilation}, 143 {"nbacc", PRO_BOOL, false, OFF, &opt.blanklines_around_conditional_compilation},
144 {"nbadp", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations_at_proctop}, 144 {"nbadp", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations_at_proctop},
145 {"nbad", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations}, 145 {"nbad", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations},
146 {"nbap", PRO_BOOL, false, OFF, &opt.blanklines_after_procs}, 146 {"nbap", PRO_BOOL, false, OFF, &opt.blanklines_after_procs},
147 {"nbbb", PRO_BOOL, false, OFF, &opt.blanklines_before_blockcomments}, 147 {"nbbb", PRO_BOOL, false, OFF, &opt.blanklines_before_blockcomments},
148 {"nbc", PRO_BOOL, true, ON, &opt.leave_comma}, 148 {"nbc", PRO_BOOL, true, ON, &opt.leave_comma},
149 {"nbs", PRO_BOOL, false, OFF, &opt.Bill_Shannon}, 149 {"nbs", PRO_BOOL, false, OFF, &opt.Bill_Shannon},
150 {"ncdb", PRO_BOOL, true, OFF, &opt.comment_delimiter_on_blankline}, 150 {"ncdb", PRO_BOOL, true, OFF, &opt.comment_delimiter_on_blankline},
151 {"nce", PRO_BOOL, true, OFF, &opt.cuddle_else}, 151 {"nce", PRO_BOOL, true, OFF, &opt.cuddle_else},
152 {"ncs", PRO_BOOL, false, OFF, &opt.space_after_cast}, 152 {"ncs", PRO_BOOL, false, OFF, &opt.space_after_cast},
153 {"ndj", PRO_BOOL, false, OFF, &opt.ljust_decl}, 153 {"ndj", PRO_BOOL, false, OFF, &opt.ljust_decl},
154 {"neei", PRO_BOOL, false, OFF, &opt.extra_expression_indent}, 154 {"neei", PRO_BOOL, false, OFF, &opt.extra_expression_indent},
155 {"nei", PRO_BOOL, true, OFF, &opt.else_if}, 155 {"nei", PRO_BOOL, true, OFF, &opt.else_if},
156 {"nfbs", PRO_BOOL, true, OFF, &opt.function_brace_split}, 156 {"nfbs", PRO_BOOL, true, OFF, &opt.function_brace_split},
157 {"nfc1", PRO_BOOL, true, OFF, &opt.format_col1_comments}, 157 {"nfc1", PRO_BOOL, true, OFF, &opt.format_col1_comments},
158 {"nfcb", PRO_BOOL, true, OFF, &opt.format_block_comments}, 158 {"nfcb", PRO_BOOL, true, OFF, &opt.format_block_comments},
159 {"nip", PRO_BOOL, true, OFF, &opt.indent_parameters}, 159 {"nip", PRO_BOOL, true, OFF, &opt.indent_parameters},
160 {"nlpl", PRO_BOOL, false, OFF, &opt.lineup_to_parens_always}, 160 {"nlpl", PRO_BOOL, false, OFF, &opt.lineup_to_parens_always},
161 {"nlp", PRO_BOOL, true, OFF, &opt.lineup_to_parens}, 161 {"nlp", PRO_BOOL, true, OFF, &opt.lineup_to_parens},
162 {"npcs", PRO_BOOL, false, OFF, &opt.proc_calls_space}, 162 {"npcs", PRO_BOOL, false, OFF, &opt.proc_calls_space},
163 {"npro", PRO_SPECIAL, 0, IGN, 0}, 163 {"npro", PRO_SPECIAL, 0, IGN, 0},
164 {"npsl", PRO_BOOL, true, OFF, &opt.procnames_start_line}, 164 {"npsl", PRO_BOOL, true, OFF, &opt.procnames_start_line},
165 {"nsc", PRO_BOOL, true, OFF, &opt.star_comment_cont}, 165 {"nsc", PRO_BOOL, true, OFF, &opt.star_comment_cont},
166 {"nsob", PRO_BOOL, false, OFF, &opt.swallow_optional_blanklines}, 166 {"nsob", PRO_BOOL, false, OFF, &opt.swallow_optional_blanklines},
167 {"nut", PRO_BOOL, true, OFF, &opt.use_tabs}, 167 {"nut", PRO_BOOL, true, OFF, &opt.use_tabs},
168 {"nv", PRO_BOOL, false, OFF, &opt.verbose}, 168 {"nv", PRO_BOOL, false, OFF, &opt.verbose},
169 {"pcs", PRO_BOOL, false, ON, &opt.proc_calls_space}, 169 {"pcs", PRO_BOOL, false, ON, &opt.proc_calls_space},
170 {"psl", PRO_BOOL, true, ON, &opt.procnames_start_line}, 170 {"psl", PRO_BOOL, true, ON, &opt.procnames_start_line},
171 {"sc", PRO_BOOL, true, ON, &opt.star_comment_cont}, 171 {"sc", PRO_BOOL, true, ON, &opt.star_comment_cont},
172 {"sob", PRO_BOOL, false, ON, &opt.swallow_optional_blanklines}, 172 {"sob", PRO_BOOL, false, ON, &opt.swallow_optional_blanklines},
173 {"st", PRO_SPECIAL, 0, STDIN, 0}, 173 {"st", PRO_SPECIAL, 0, STDIN, 0},
174 {"ta", PRO_BOOL, false, ON, &opt.auto_typedefs}, 174 {"ta", PRO_BOOL, false, ON, &opt.auto_typedefs},
175 {"ts", PRO_INT, 8, 0, &opt.tabsize}, 175 {"ts", PRO_INT, 8, 0, &opt.tabsize},
176 {"ut", PRO_BOOL, true, ON, &opt.use_tabs}, 176 {"ut", PRO_BOOL, true, ON, &opt.use_tabs},
177 {"v", PRO_BOOL, false, ON, &opt.verbose}, 177 {"v", PRO_BOOL, false, ON, &opt.verbose},
178 /* whew! */ 178 /* whew! */
179 {0, 0, 0, 0, 0} 179 {0, 0, 0, 0, 0}
180}; 180};
181 181
182/* 182/*
183 * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments 183 * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
184 * given in these files. 184 * given in these files.
185 */ 185 */
186void 186void
187set_profile(const char *profile_name) 187set_profile(const char *profile_name)
188{ 188{
189 FILE *f; 189 FILE *f;
190 char fname[PATH_MAX]; 190 char fname[PATH_MAX];
191 static char prof[] = ".indent.pro"; 191 static char prof[] = ".indent.pro";
192 192
193 if (profile_name == NULL) 193 if (profile_name == NULL)
194 snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); 194 snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
195 else 195 else
196 snprintf(fname, sizeof(fname), "%s", profile_name + 2); 196 snprintf(fname, sizeof(fname), "%s", profile_name + 2);
197 if ((f = fopen(option_source = fname, "r")) != NULL) { 197 if ((f = fopen(option_source = fname, "r")) != NULL) {
198 scan_profile(f); 198 scan_profile(f);
199 (void) fclose(f); 199 (void) fclose(f);
200 } 200 }
201 if ((f = fopen(option_source = prof, "r")) != NULL) { 201 if ((f = fopen(option_source = prof, "r")) != NULL) {
202 scan_profile(f); 202 scan_profile(f);
203 (void) fclose(f); 203 (void) fclose(f);
204 } 204 }
205 option_source = "Command line"; 205 option_source = "Command line";
206} 206}
207 207
208static void 208static void
209scan_profile(FILE *f) 209scan_profile(FILE *f)
210{ 210{
211 int comment_index, i; 211 int comment_index, i;
212 char *p; 212 char *p;
213 char buf[BUFSIZ]; 213 char buf[BUFSIZ];
214 214
215 while (1) { 215 while (1) {
216 p = buf; 216 p = buf;
217 comment_index = 0; 217 comment_index = 0;
218 while ((i = getc(f)) != EOF) { 218 while ((i = getc(f)) != EOF) {
219 if (i == '*' && !comment_index && p > buf && p[-1] == '/') { 219 if (i == '*' && !comment_index && p > buf && p[-1] == '/') {
220 comment_index = p - buf; 220 comment_index = p - buf;
221 *p++ = i; 221 *p++ = i;
222 } else if (i == '/' && comment_index && p > buf && p[-1] == '*') { 222 } else if (i == '/' && comment_index && p > buf && p[-1] == '*') {
223 p = buf + comment_index - 1; 223 p = buf + comment_index - 1;
224 comment_index = 0; 224 comment_index = 0;
225 } else if (isspace((unsigned char)i)) { 225 } else if (isspace((unsigned char)i)) {
226 if (p > buf && !comment_index) 226 if (p > buf && !comment_index)
227 break; 227 break;
228 } else { 228 } else {
229 *p++ = i; 229 *p++ = i;
230 } 230 }
231 } 231 }
232 if (p != buf) { 232 if (p != buf) {
233 *p++ = 0; 233 *p++ = 0;
234 if (opt.verbose) 234 if (opt.verbose)
235 printf("profile: %s\n", buf); 235 printf("profile: %s\n", buf);
236 set_option(buf); 236 set_option(buf);
237 } 237 } else if (i == EOF)
238 else if (i == EOF) 
239 return; 238 return;
240 } 239 }
241} 240}
242 241
243static const char * 242static const char *
244eqin(const char *s1, const char *s2) 243eqin(const char *s1, const char *s2)
245{ 244{
246 while (*s1) { 245 while (*s1) {
247 if (*s1++ != *s2++) 246 if (*s1++ != *s2++)
248 return NULL; 247 return NULL;
249 } 248 }
250 return s2; 249 return s2;
251} 250}
252 251
253/* 252/*
254 * Set the defaults. 253 * Set the defaults.
255 */ 254 */
256void 255void
257set_defaults(void) 256set_defaults(void)
258{ 257{
259 /* 258 /*
260 * Because ps.case_indent is a float, we can't initialize it from the 259 * Because ps.case_indent is a float, we can't initialize it from the
261 * table: 260 * table:
262 */ 261 */
263 opt.case_indent = 0.0F; /* -cli0.0 */ 262 opt.case_indent = 0.0F; /* -cli0.0 */
264 263
265 for (const struct pro *p = pro; p->p_name; p++) 264 for (const struct pro *p = pro; p->p_name; p++)
266 if (p->p_type != PRO_SPECIAL) 265 if (p->p_type != PRO_SPECIAL)
267 *p->p_obj = p->p_default; 266 *p->p_obj = p->p_default;
268} 267}
269 268
270void 269void
271set_option(char *arg) 270set_option(char *arg)
272{ 271{
273 const struct pro *p; 272 const struct pro *p;
274 const char *param_start; 273 const char *param_start;
275 274
276 arg++; /* ignore leading "-" */ 275 arg++; /* ignore leading "-" */
277 for (p = pro; p->p_name; p++) 276 for (p = pro; p->p_name; p++)
278 if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL) 277 if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL)
279 goto found; 278 goto found;
280 errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); 279 errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1);
281found: 280found:
282 switch (p->p_type) { 281 switch (p->p_type) {
283 282
284 case PRO_SPECIAL: 283 case PRO_SPECIAL:
285 switch (p->p_special) { 284 switch (p->p_special) {
286 285
287 case IGN: 286 case IGN:
288 break; 287 break;
289 288
290 case CLI: 289 case CLI:
291 if (*param_start == 0) 290 if (*param_start == 0)
292 goto need_param; 291 goto need_param;
293 opt.case_indent = atof(param_start); 292 opt.case_indent = atof(param_start);
294 break; 293 break;
295 294
296 case STDIN: 295 case STDIN:
297 if (input == NULL) 296 if (input == NULL)
298 input = stdin; 297 input = stdin;
299 if (output == NULL) 298 if (output == NULL)
300 output = stdout; 299 output = stdout;
301 break; 300 break;
302 301
303 case KEY: 302 case KEY:
304 if (*param_start == 0) 303 if (*param_start == 0)
305 goto need_param; 304 goto need_param;
306 add_typename(param_start); 305 add_typename(param_start);
307 break; 306 break;
308 307
309 case KEY_FILE: 308 case KEY_FILE:
310 if (*param_start == 0) 309 if (*param_start == 0)
311 goto need_param; 310 goto need_param;
312 add_typedefs_from_file(param_start); 311 add_typedefs_from_file(param_start);
313 break; 312 break;
314 313
315 case VERSION: 314 case VERSION:
316 printf("FreeBSD indent %s\n", INDENT_VERSION); 315 printf("FreeBSD indent %s\n", INDENT_VERSION);
317 exit(0); 316 exit(0);
318 317
319 default: 318 default:
320 errx(1, "set_option: internal error: p_special %d", p->p_special); 319 errx(1, "set_option: internal error: p_special %d", p->p_special);
321 } 320 }
322 break; 321 break;
323 322
324 case PRO_BOOL: 323 case PRO_BOOL:
325 if (p->p_special == OFF) 324 if (p->p_special == OFF)
326 *p->p_obj = false; 325 *p->p_obj = false;
327 else 326 else
328 *p->p_obj = true; 327 *p->p_obj = true;
329 break; 328 break;
330 329
331 case PRO_INT: 330 case PRO_INT:
332 if (!isdigit((unsigned char)*param_start)) { 331 if (!isdigit((unsigned char)*param_start)) {
333 need_param: 332 need_param:
334 errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name); 333 errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name);
335 } 334 }
336 *p->p_obj = atoi(param_start); 335 *p->p_obj = atoi(param_start);
337 break; 336 break;
338 337
339 default: 338 default:
340 errx(1, "set_option: internal error: p_type %d", p->p_type); 339 errx(1, "set_option: internal error: p_type %d", p->p_type);
341 } 340 }
342} 341}
343 342
344void 343void
345add_typedefs_from_file(const char *str) 344add_typedefs_from_file(const char *str)
346{ 345{
347 FILE *file; 346 FILE *file;
348 char line[BUFSIZ]; 347 char line[BUFSIZ];
349 348
350 if ((file = fopen(str, "r")) == NULL) { 349 if ((file = fopen(str, "r")) == NULL) {
351 fprintf(stderr, "indent: cannot open file %s\n", str); 350 fprintf(stderr, "indent: cannot open file %s\n", str);
352 exit(1); 351 exit(1);
353 } 352 }
354 while ((fgets(line, BUFSIZ, file)) != NULL) { 353 while ((fgets(line, BUFSIZ, file)) != NULL) {
355 /* Remove trailing whitespace */ 354 /* Remove trailing whitespace */
356 line[strcspn(line, " \t\n\r")] = '\0'; 355 line[strcspn(line, " \t\n\r")] = '\0';
357 add_typename(line); 356 add_typename(line);
358 } 357 }
359 fclose(file); 358 fclose(file);
360} 359}

cvs diff -r1.18 -r1.19 src/usr.bin/indent/pr_comment.c (switch to unified diff)

--- src/usr.bin/indent/pr_comment.c 2021/03/11 22:32:06 1.18
+++ src/usr.bin/indent/pr_comment.c 2021/03/12 23:10:18 1.19
@@ -1,389 +1,381 @@ @@ -1,389 +1,381 @@
1/* $NetBSD: pr_comment.c,v 1.18 2021/03/11 22:32:06 rillig Exp $ */ 1/* $NetBSD: pr_comment.c,v 1.19 2021/03/12 23:10:18 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[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; 42static char sccsid[] = "@(#)pr_comment.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: pr_comment.c,v 1.18 2021/03/11 22:32:06 rillig Exp $"); 49__RCSID("$NetBSD: pr_comment.c,v 1.19 2021/03/12 23:10:18 rillig Exp $");
50#elif defined(__FreeBSD__) 50#elif defined(__FreeBSD__)
51__FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $");
52#endif 52#endif
53#endif 53#endif
54 54
55#include <err.h> 55#include <err.h>
56#include <stdio.h> 56#include <stdio.h>
57#include <stdlib.h> 57#include <stdlib.h>
58#include <string.h> 58#include <string.h>
59 59
60#include "indent.h" 60#include "indent.h"
61 61
62static void 62static void
63check_size_comment(size_t desired_size, char **last_bl_ptr) 63check_size_comment(size_t desired_size, char **last_bl_ptr)
64{ 64{
65 if (e_com + (desired_size) < l_com) 65 if (e_com + (desired_size) < l_com)
66 return; 66 return;
67 67
68 size_t nsize = l_com - s_com + 400 + desired_size; 68 size_t nsize = l_com - s_com + 400 + desired_size;
69 size_t com_len = e_com - s_com; 69 size_t com_len = e_com - s_com;
70 ssize_t blank_pos = *last_bl_ptr != NULL ? *last_bl_ptr - combuf : -1; 70 ssize_t blank_pos = *last_bl_ptr != NULL ? *last_bl_ptr - combuf : -1;
71 combuf = realloc(combuf, nsize); 71 combuf = realloc(combuf, nsize);
72 if (combuf == NULL) 72 if (combuf == NULL)
73 err(1, NULL); 73 err(1, NULL);
74 e_com = combuf + com_len + 1; 74 e_com = combuf + com_len + 1;
75 if (blank_pos > 0) 75 if (blank_pos > 0)
76 *last_bl_ptr = combuf + blank_pos; 76 *last_bl_ptr = combuf + blank_pos;
77 l_com = combuf + nsize - 5; 77 l_com = combuf + nsize - 5;
78 s_com = combuf + 1; 78 s_com = combuf + 1;
79} 79}
80 80
81/* 81/*
82 * NAME: 82 * NAME:
83 * pr_comment 83 * pr_comment
84 * 84 *
85 * FUNCTION: 85 * FUNCTION:
86 * This routine takes care of scanning and printing comments. 86 * This routine takes care of scanning and printing comments.
87 * 87 *
88 * ALGORITHM: 88 * ALGORITHM:
89 * 1) Decide where the comment should be aligned, and if lines should 89 * 1) Decide where the comment should be aligned, and if lines should
90 * be broken. 90 * be broken.
91 * 2) If lines should not be broken and filled, just copy up to end of 91 * 2) If lines should not be broken and filled, just copy up to end of
92 * comment. 92 * comment.
93 * 3) If lines should be filled, then scan thru input_buffer copying 93 * 3) If lines should be filled, then scan thru input_buffer copying
94 * characters to com_buf. Remember where the last blank, tab, or 94 * characters to com_buf. Remember where the last blank, tab, or
95 * newline was. When line is filled, print up to last blank and 95 * newline was. When line is filled, print up to last blank and
96 * continue copying. 96 * continue copying.
97 * 97 *
98 * HISTORY: 98 * HISTORY:
99 * November 1976 D A Willcox of CAC Initial coding 99 * November 1976 D A Willcox of CAC Initial coding
100 * 12/6/76 D A Willcox of CAC Modification to handle 100 * 12/6/76 D A Willcox of CAC Modification to handle
101 * UNIX-style comments 101 * UNIX-style comments
102 * 102 *
103 */  103 */
104 104
105/* 105/*
106 * this routine processes comments. It makes an attempt to keep comments from 106 * this routine processes comments. It makes an attempt to keep comments from
107 * going over the max line length. If a line is too long, it moves everything 107 * going over the max line length. If a line is too long, it moves everything
108 * from the last blank to the next comment line. Blanks and tabs from the 108 * from the last blank to the next comment line. Blanks and tabs from the
109 * beginning of the input line are removed 109 * beginning of the input line are removed
110 */ 110 */
111 111
112void 112void
113pr_comment(void) 113pr_comment(void)
114{ 114{
115 int now_col; /* column we are in now */ 115 int now_col; /* column we are in now */
116 int adj_max_col; /* Adjusted max_col for when we decide to 116 int adj_max_col; /* Adjusted max_col for when we decide to
117 * spill comments over the right margin */ 117 * spill comments over the right margin */
118 char *last_bl; /* points to the last blank in the output 118 char *last_bl; /* points to the last blank in the output
119 * buffer */ 119 * buffer */
120 char *t_ptr; /* used for moving string */ 120 char *t_ptr; /* used for moving string */
121 int break_delim = opt.comment_delimiter_on_blankline; 121 int break_delim = opt.comment_delimiter_on_blankline;
122 int l_just_saw_decl = ps.just_saw_decl; 122 int l_just_saw_decl = ps.just_saw_decl;
123 123
124 adj_max_col = opt.max_col; 124 adj_max_col = opt.max_col;
125 ps.just_saw_decl = 0; 125 ps.just_saw_decl = 0;
126 last_bl = NULL; /* no blanks found so far */ 126 last_bl = NULL; /* no blanks found so far */
127 ps.box_com = false; /* at first, assume that we are not in 127 ps.box_com = false; /* at first, assume that we are not in
128 * a boxed comment or some other 128 * a boxed comment or some other
129 * comment that should not be touched */ 129 * comment that should not be touched */
130 ++ps.out_coms; /* keep track of number of comments */ 130 ++ps.out_coms; /* keep track of number of comments */
131 131
132 /* Figure where to align and how to treat the comment */ 132 /* Figure where to align and how to treat the comment */
133 133
134 if (ps.col_1 && !opt.format_col1_comments) { /* if comment starts in column 134 if (ps.col_1 && !opt.format_col1_comments) { /* if comment starts in column
135 * 1 it should not be touched */ 135 * 1 it should not be touched */
136 ps.box_com = true; 136 ps.box_com = true;
137 break_delim = false; 137 break_delim = false;
138 ps.com_col = 1; 138 ps.com_col = 1;
139 } 139 } else {
140 else { 
141 if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' || 140 if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' ||
142 (*buf_ptr == '\n' && !opt.format_block_comments)) { 141 (*buf_ptr == '\n' && !opt.format_block_comments)) {
143 ps.box_com = true; /* A comment with a '-' or '*' immediately 142 ps.box_com = true; /* A comment with a '-' or '*' immediately
144 * after the /+* is assumed to be a boxed 143 * after the /+* is assumed to be a boxed
145 * comment. A comment with a newline 144 * comment. A comment with a newline
146 * immediately after the /+* is assumed to 145 * immediately after the /+* is assumed to
147 * be a block comment and is treated as a 146 * be a block comment and is treated as a
148 * box comment unless format_block_comments 147 * box comment unless format_block_comments
149 * is nonzero (the default). */ 148 * is nonzero (the default). */
150 break_delim = false; 149 break_delim = false;
151 } 150 }
152 if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { 151 if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
153 /* klg: check only if this line is blank */ 152 /* klg: check only if this line is blank */
154 /* 153 /*
155 * If this (*and previous lines are*) blank, dont put comment way 154 * If this (*and previous lines are*) blank, dont put comment way
156 * out at left 155 * out at left
157 */ 156 */
158 ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1; 157 ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1;
159 adj_max_col = opt.block_comment_max_col; 158 adj_max_col = opt.block_comment_max_col;
160 if (ps.com_col <= 1) 159 if (ps.com_col <= 1)
161 ps.com_col = 1 + !opt.format_col1_comments; 160 ps.com_col = 1 + !opt.format_col1_comments;
162 } 161 } else {
163 else { 
164 int target_col; 162 int target_col;
165 break_delim = false; 163 break_delim = false;
166 if (s_code != e_code) 164 if (s_code != e_code)
167 target_col = count_spaces(compute_code_target(), s_code); 165 target_col = count_spaces(compute_code_target(), s_code);
168 else { 166 else {
169 target_col = 1; 167 target_col = 1;
170 if (s_lab != e_lab) 168 if (s_lab != e_lab)
171 target_col = count_spaces(compute_label_target(), s_lab); 169 target_col = count_spaces(compute_label_target(), s_lab);
172 } 170 }
173 ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind; 171 ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind;
174 if (ps.com_col <= target_col) 172 if (ps.com_col <= target_col)
175 ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; 173 ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1;
176 if (ps.com_col + 24 > adj_max_col) 174 if (ps.com_col + 24 > adj_max_col)
177 adj_max_col = ps.com_col + 24; 175 adj_max_col = ps.com_col + 24;
178 } 176 }
179 } 177 }
180 if (ps.box_com) { 178 if (ps.box_com) {
181 /* 179 /*
182 * Find out how much indentation there was originally, because that 180 * Find out how much indentation there was originally, because that
183 * much will have to be ignored by pad_output() in dump_line(). This 181 * much will have to be ignored by pad_output() in dump_line(). This
184 * is a box comment, so nothing changes -- not even indentation. 182 * is a box comment, so nothing changes -- not even indentation.
185 * 183 *
186 * The comment we're about to read usually comes from in_buffer, 184 * The comment we're about to read usually comes from in_buffer,
187 * unless it has been copied into save_com. 185 * unless it has been copied into save_com.
188 */ 186 */
189 char *start; 187 char *start;
190 188
191 start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? 189 start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ?
192 sc_buf : in_buffer; 190 sc_buf : in_buffer;
193 ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2); 191 ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2);
194 } 192 } else {
195 else { 
196 ps.n_comment_delta = 0; 193 ps.n_comment_delta = 0;
197 while (*buf_ptr == ' ' || *buf_ptr == '\t') 194 while (*buf_ptr == ' ' || *buf_ptr == '\t')
198 buf_ptr++; 195 buf_ptr++;
199 } 196 }
200 ps.comment_delta = 0; 197 ps.comment_delta = 0;
201 *e_com++ = '/'; 198 *e_com++ = '/';
202 *e_com++ = e_token[-1]; 199 *e_com++ = e_token[-1];
203 if (*buf_ptr != ' ' && !ps.box_com) 200 if (*buf_ptr != ' ' && !ps.box_com)
204 *e_com++ = ' '; 201 *e_com++ = ' ';
205 202
206 /* 203 /*
207 * Don't put a break delimiter if this is a one-liner that won't wrap. 204 * Don't put a break delimiter if this is a one-liner that won't wrap.
208 */ 205 */
209 if (break_delim) 206 if (break_delim)
210 for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { 207 for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) {
211 if (t_ptr >= buf_end) 208 if (t_ptr >= buf_end)
212 fill_buffer(); 209 fill_buffer();
213 if (t_ptr[0] == '*' && t_ptr[1] == '/') { 210 if (t_ptr[0] == '*' && t_ptr[1] == '/') {
214 if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2)) 211 if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2))
215 break_delim = false; 212 break_delim = false;
216 break; 213 break;
217 } 214 }
218 } 215 }
219 216
220 if (break_delim) { 217 if (break_delim) {
221 char *t = e_com; 218 char *t = e_com;
222 e_com = s_com + 2; 219 e_com = s_com + 2;
223 *e_com = 0; 220 *e_com = 0;
224 if (opt.blanklines_before_blockcomments && ps.last_token != lbrace) 221 if (opt.blanklines_before_blockcomments && ps.last_token != lbrace)
225 prefix_blankline_requested = 1; 222 prefix_blankline_requested = 1;
226 dump_line(); 223 dump_line();
227 e_com = s_com = t; 224 e_com = s_com = t;
228 if (!ps.box_com && opt.star_comment_cont) 225 if (!ps.box_com && opt.star_comment_cont)
229 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 226 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
230 } 227 }
231 228
232 /* Start to copy the comment */ 229 /* Start to copy the comment */
233 230
234 while (1) { /* this loop will go until the comment is 231 while (1) { /* this loop will go until the comment is
235 * copied */ 232 * copied */
236 switch (*buf_ptr) { /* this checks for various spcl cases */ 233 switch (*buf_ptr) { /* this checks for various spcl cases */
237 case 014: /* check for a form feed */ 234 case 014: /* check for a form feed */
238 check_size_comment(3, &last_bl); 235 check_size_comment(3, &last_bl);
239 if (!ps.box_com) { /* in a text comment, break the line here */ 236 if (!ps.box_com) { /* in a text comment, break the line here */
240 ps.use_ff = true; 237 ps.use_ff = true;
241 /* fix so dump_line uses a form feed */ 238 /* fix so dump_line uses a form feed */
242 dump_line(); 239 dump_line();
243 last_bl = NULL; 240 last_bl = NULL;
244 if (!ps.box_com && opt.star_comment_cont) 241 if (!ps.box_com && opt.star_comment_cont)
245 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 242 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
246 while (*++buf_ptr == ' ' || *buf_ptr == '\t') 243 while (*++buf_ptr == ' ' || *buf_ptr == '\t')
247 ; 244 ;
248 } 245 } else {
249 else { 
250 if (++buf_ptr >= buf_end) 246 if (++buf_ptr >= buf_end)
251 fill_buffer(); 247 fill_buffer();
252 *e_com++ = 014; 248 *e_com++ = 014;
253 } 249 }
254 break; 250 break;
255 251
256 case '\n': 252 case '\n':
257 if (e_token[-1] == '/') { 253 if (e_token[-1] == '/') {
258 ++line_no; 254 ++line_no;
259 goto end_of_comment; 255 goto end_of_comment;
260 } 256 }
261 if (had_eof) { /* check for unexpected eof */ 257 if (had_eof) { /* check for unexpected eof */
262 printf("Unterminated comment\n"); 258 printf("Unterminated comment\n");
263 dump_line(); 259 dump_line();
264 return; 260 return;
265 } 261 }
266 last_bl = NULL; 262 last_bl = NULL;
267 check_size_comment(4, &last_bl); 263 check_size_comment(4, &last_bl);
268 if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, 264 if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
269 * we dont ignore the newline */ 265 * we dont ignore the newline */
270 if (s_com == e_com) 266 if (s_com == e_com)
271 *e_com++ = ' '; 267 *e_com++ = ' ';
272 if (!ps.box_com && e_com - s_com > 3) { 268 if (!ps.box_com && e_com - s_com > 3) {
273 dump_line(); 269 dump_line();
274 if (opt.star_comment_cont) 270 if (opt.star_comment_cont)
275 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 271 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
276 } 272 }
277 dump_line(); 273 dump_line();
278 if (!ps.box_com && opt.star_comment_cont) 274 if (!ps.box_com && opt.star_comment_cont)
279 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 275 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
280 } 276 } else {
281 else { 
282 ps.last_nl = 1; 277 ps.last_nl = 1;
283 if (e_com[-1] == ' ' || e_com[-1] == '\t') 278 if (e_com[-1] == ' ' || e_com[-1] == '\t')
284 last_bl = e_com - 1; 279 last_bl = e_com - 1;
285 /* 280 /*
286 * if there was a space at the end of the last line, remember 281 * if there was a space at the end of the last line, remember
287 * where it was 282 * where it was
288 */ 283 */
289 else { /* otherwise, insert one */ 284 else { /* otherwise, insert one */
290 last_bl = e_com; 285 last_bl = e_com;
291 *e_com++ = ' '; 286 *e_com++ = ' ';
292 } 287 }
293 } 288 }
294 ++line_no; /* keep track of input line number */ 289 ++line_no; /* keep track of input line number */
295 if (!ps.box_com) { 290 if (!ps.box_com) {
296 int nstar = 1; 291 int nstar = 1;
297 do { /* flush any blanks and/or tabs at start of 292 do { /* flush any blanks and/or tabs at start of
298 * next line */ 293 * next line */
299 if (++buf_ptr >= buf_end) 294 if (++buf_ptr >= buf_end)
300 fill_buffer(); 295 fill_buffer();
301 if (*buf_ptr == '*' && --nstar >= 0) { 296 if (*buf_ptr == '*' && --nstar >= 0) {
302 if (++buf_ptr >= buf_end) 297 if (++buf_ptr >= buf_end)
303 fill_buffer(); 298 fill_buffer();
304 if (*buf_ptr == '/') 299 if (*buf_ptr == '/')
305 goto end_of_comment; 300 goto end_of_comment;
306 } 301 }
307 } while (*buf_ptr == ' ' || *buf_ptr == '\t'); 302 } while (*buf_ptr == ' ' || *buf_ptr == '\t');
308 } 303 } else if (++buf_ptr >= buf_end)
309 else if (++buf_ptr >= buf_end) 
310 fill_buffer(); 304 fill_buffer();
311 break; /* end of case for newline */ 305 break; /* end of case for newline */
312 306
313 case '*': /* must check for possibility of being at end 307 case '*': /* must check for possibility of being at end
314 * of comment */ 308 * of comment */
315 if (++buf_ptr >= buf_end) /* get to next char after * */ 309 if (++buf_ptr >= buf_end) /* get to next char after * */
316 fill_buffer(); 310 fill_buffer();
317 check_size_comment(4, &last_bl); 311 check_size_comment(4, &last_bl);
318 if (*buf_ptr == '/') { /* it is the end!!! */ 312 if (*buf_ptr == '/') { /* it is the end!!! */
319 end_of_comment: 313 end_of_comment:
320 if (++buf_ptr >= buf_end) 314 if (++buf_ptr >= buf_end)
321 fill_buffer(); 315 fill_buffer();
322 if (break_delim) { 316 if (break_delim) {
323 if (e_com > s_com + 3) { 317 if (e_com > s_com + 3)
324 dump_line(); 318 dump_line();
325 } 
326 else 319 else
327 s_com = e_com; 320 s_com = e_com;
328 *e_com++ = ' '; 321 *e_com++ = ' ';
329 } 322 }
330 if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) 323 if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com)
331 *e_com++ = ' '; /* ensure blank before end */ 324 *e_com++ = ' '; /* ensure blank before end */
332 if (e_token[-1] == '/') 325 if (e_token[-1] == '/')
333 *e_com++ = '\n', *e_com = '\0'; 326 *e_com++ = '\n', *e_com = '\0';
334 else 327 else
335 *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; 328 *e_com++ = '*', *e_com++ = '/', *e_com = '\0';
336 ps.just_saw_decl = l_just_saw_decl; 329 ps.just_saw_decl = l_just_saw_decl;
337 return; 330 return;
338 } 331 } else /* handle isolated '*' */
339 else /* handle isolated '*' */ 
340 *e_com++ = '*'; 332 *e_com++ = '*';
341 break; 333 break;
342 default: /* we have a random char */ 334 default: /* we have a random char */
343 now_col = count_spaces_until(ps.com_col, s_com, e_com); 335 now_col = count_spaces_until(ps.com_col, s_com, e_com);
344 do { 336 do {
345 check_size_comment(1, &last_bl); 337 check_size_comment(1, &last_bl);
346 *e_com = *buf_ptr++; 338 *e_com = *buf_ptr++;
347 if (buf_ptr >= buf_end) 339 if (buf_ptr >= buf_end)
348 fill_buffer(); 340 fill_buffer();
349 if (*e_com == ' ' || *e_com == '\t') 341 if (*e_com == ' ' || *e_com == '\t')
350 last_bl = e_com; /* remember we saw a blank */ 342 last_bl = e_com; /* remember we saw a blank */
351 ++e_com; 343 ++e_com;
352 now_col++; 344 now_col++;
353 } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && 345 } while (!memchr("*\n\r\b\t", *buf_ptr, 6) &&
354 (now_col <= adj_max_col || !last_bl)); 346 (now_col <= adj_max_col || !last_bl));
355 ps.last_nl = false; 347 ps.last_nl = false;
356 if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') { 348 if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') {
357 /* 349 /*
358 * the comment is too long, it must be broken up 350 * the comment is too long, it must be broken up
359 */ 351 */
360 if (last_bl == NULL) { 352 if (last_bl == NULL) {
361 dump_line(); 353 dump_line();
362 if (!ps.box_com && opt.star_comment_cont) 354 if (!ps.box_com && opt.star_comment_cont)
363 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 355 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
364 break; 356 break;
365 } 357 }
366 *e_com = '\0'; 358 *e_com = '\0';
367 e_com = last_bl; 359 e_com = last_bl;
368 dump_line(); 360 dump_line();
369 if (!ps.box_com && opt.star_comment_cont) 361 if (!ps.box_com && opt.star_comment_cont)
370 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; 362 *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
371 for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; 363 for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t';
372 t_ptr++) 364 t_ptr++)
373 ; 365 ;
374 last_bl = NULL; 366 last_bl = NULL;
375 /* 367 /*
376 * t_ptr will be somewhere between e_com (dump_line() reset) 368 * t_ptr will be somewhere between e_com (dump_line() reset)
377 * and l_com. So it's safe to copy byte by byte from t_ptr 369 * and l_com. So it's safe to copy byte by byte from t_ptr
378 * to e_com without any check_size_comment(). 370 * to e_com without any check_size_comment().
379 */ 371 */
380 while (*t_ptr != '\0') { 372 while (*t_ptr != '\0') {
381 if (*t_ptr == ' ' || *t_ptr == '\t') 373 if (*t_ptr == ' ' || *t_ptr == '\t')
382 last_bl = e_com; 374 last_bl = e_com;
383 *e_com++ = *t_ptr++; 375 *e_com++ = *t_ptr++;
384 } 376 }
385 } 377 }
386 break; 378 break;
387 } 379 }
388 } 380 }
389} 381}

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

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

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

--- src/usr.bin/indent/io.c 2021/03/12 19:14:18 1.29
+++ src/usr.bin/indent/io.c 2021/03/12 23:10:18 1.30
@@ -1,545 +1,540 @@ @@ -1,545 +1,540 @@
1/* $NetBSD: io.c,v 1.29 2021/03/12 19:14:18 rillig Exp $ */ 1/* $NetBSD: io.c,v 1.30 2021/03/12 23:10:18 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[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; 42static char sccsid[] = "@(#)io.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: io.c,v 1.29 2021/03/12 19:14:18 rillig Exp $"); 49__RCSID("$NetBSD: io.c,v 1.30 2021/03/12 23:10:18 rillig Exp $");
50#elif defined(__FreeBSD__) 50#elif defined(__FreeBSD__)
51__FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $");
52#endif 52#endif
53#endif 53#endif
54 54
55#include <ctype.h> 55#include <ctype.h>
56#include <err.h> 56#include <err.h>
57#include <stdio.h> 57#include <stdio.h>
58#include <stdlib.h> 58#include <stdlib.h>
59#include <string.h> 59#include <string.h>
60#include <stdarg.h> 60#include <stdarg.h>
61 61
62#include "indent.h" 62#include "indent.h"
63 63
64int comment_open; 64int comment_open;
65static int paren_target; 65static int paren_target;
66static int pad_output(int current, int target); 66static int pad_output(int current, int target);
67 67
68static void 68static void
69output_char(char ch) 69output_char(char ch)
70{ 70{
71 fputc(ch, output); 71 fputc(ch, output);
72} 72}
73 73
74static void 74static void
75output_range(const char *s, const char *e) 75output_range(const char *s, const char *e)
76{ 76{
77 fwrite(s, 1, (size_t)(e - s), output); 77 fwrite(s, 1, (size_t)(e - s), output);
78} 78}
79 79
80static inline void 80static inline void
81output_string(const char *s) 81output_string(const char *s)
82{ 82{
83 output_range(s, s + strlen(s)); 83 output_range(s, s + strlen(s));
84} 84}
85 85
86static void 86static void
87output_int(int i) 87output_int(int i)
88{ 88{
89 fprintf(output, "%d", i); 89 fprintf(output, "%d", i);
90} 90}
91 91
92/* 92/*
93 * dump_line is the routine that actually effects the printing of the new 93 * dump_line is the routine that actually effects the printing of the new
94 * source. It prints the label section, followed by the code section with 94 * source. It prints the label section, followed by the code section with
95 * the appropriate nesting level, followed by any comments. 95 * the appropriate nesting level, followed by any comments.
96 */ 96 */
97void 97void
98dump_line(void) 98dump_line(void)
99{ 99{
100 int cur_col, target_col; 100 int cur_col, target_col;
101 static int not_first_line; 101 static int not_first_line;
102 102
103 if (ps.procname[0]) { 103 if (ps.procname[0]) {
104 ps.ind_level = 0; 104 ps.ind_level = 0;
105 ps.procname[0] = 0; 105 ps.procname[0] = 0;
106 } 106 }
 107
107 if (s_code == e_code && s_lab == e_lab && s_com == e_com) { 108 if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
108 if (suppress_blanklines > 0) 109 if (suppress_blanklines > 0)
109 suppress_blanklines--; 110 suppress_blanklines--;
110 else { 111 else {
111 ps.bl_line = true; 112 ps.bl_line = true;
112 n_real_blanklines++; 113 n_real_blanklines++;
113 } 114 }
114 } 115 } else if (!inhibit_formatting) {
115 else if (!inhibit_formatting) { 
116 suppress_blanklines = 0; 116 suppress_blanklines = 0;
117 ps.bl_line = false; 117 ps.bl_line = false;
118 if (prefix_blankline_requested && not_first_line) { 118 if (prefix_blankline_requested && not_first_line) {
119 if (opt.swallow_optional_blanklines) { 119 if (opt.swallow_optional_blanklines) {
120 if (n_real_blanklines == 1) 120 if (n_real_blanklines == 1)
121 n_real_blanklines = 0; 121 n_real_blanklines = 0;
122 } 122 } else {
123 else { 
124 if (n_real_blanklines == 0) 123 if (n_real_blanklines == 0)
125 n_real_blanklines = 1; 124 n_real_blanklines = 1;
126 } 125 }
127 } 126 }
128 while (--n_real_blanklines >= 0) 127 while (--n_real_blanklines >= 0)
129 output_char('\n'); 128 output_char('\n');
130 n_real_blanklines = 0; 129 n_real_blanklines = 0;
131 if (ps.ind_level == 0) 130 if (ps.ind_level == 0)
132 ps.ind_stmt = 0; /* this is a class A kludge. dont do 131 ps.ind_stmt = 0; /* this is a class A kludge. dont do
133 * additional statement indentation if we are 132 * additional statement indentation if we are
134 * at bracket level 0 */ 133 * at bracket level 0 */
135 134
136 if (e_lab != s_lab || e_code != s_code) 135 if (e_lab != s_lab || e_code != s_code)
137 ++code_lines; /* keep count of lines with code */ 136 ++code_lines; /* keep count of lines with code */
138 137
139 138
140 if (e_lab != s_lab) { /* print lab, if any */ 139 if (e_lab != s_lab) { /* print lab, if any */
141 if (comment_open) { 140 if (comment_open) {
142 comment_open = 0; 141 comment_open = 0;
143 output_string(".*/\n"); 142 output_string(".*/\n");
144 } 143 }
145 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) 144 while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
146 e_lab--; 145 e_lab--;
147 *e_lab = '\0'; 146 *e_lab = '\0';
148 cur_col = pad_output(1, compute_label_target()); 147 cur_col = pad_output(1, compute_label_target());
149 if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 148 if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0
150 || strncmp(s_lab, "#endif", 6) == 0)) { 149 || strncmp(s_lab, "#endif", 6) == 0)) {
151 char *s = s_lab; 150 char *s = s_lab;
152 if (e_lab[-1] == '\n') e_lab--; 151 if (e_lab[-1] == '\n') e_lab--;
153 do { 152 do {
154 output_char(*s++); 153 output_char(*s++);
155 } while (s < e_lab && 'a' <= *s && *s <= 'z'); 154 } while (s < e_lab && 'a' <= *s && *s <= 'z');
156 while ((*s == ' ' || *s == '\t') && s < e_lab) 155 while ((*s == ' ' || *s == '\t') && s < e_lab)
157 s++; 156 s++;
158 if (s < e_lab) { 157 if (s < e_lab) {
159 if (s[0] == '/' && s[1] == '*') { 158 if (s[0] == '/' && s[1] == '*') {
160 output_char('\t'); 159 output_char('\t');
161 output_range(s, e_lab); 160 output_range(s, e_lab);
162 } else { 161 } else {
163 output_string("\t/* "); 162 output_string("\t/* ");
164 output_range(s, e_lab); 163 output_range(s, e_lab);
165 output_string(" */"); 164 output_string(" */");
166 } 165 }
167 } 166 }
168 } else 167 } else
169 output_range(s_lab, e_lab); 168 output_range(s_lab, e_lab);
170 cur_col = count_spaces(cur_col, s_lab); 169 cur_col = count_spaces(cur_col, s_lab);
171 } 170 } else
172 else 
173 cur_col = 1; /* there is no label section */ 171 cur_col = 1; /* there is no label section */
174 172
175 ps.pcase = false; 173 ps.pcase = false;
176 174
177 if (s_code != e_code) { /* print code section, if any */ 175 if (s_code != e_code) { /* print code section, if any */
178 char *p; 176 char *p;
179 177
180 if (comment_open) { 178 if (comment_open) {
181 comment_open = 0; 179 comment_open = 0;
182 output_string(".*/\n"); 180 output_string(".*/\n");
183 } 181 }
184 target_col = compute_code_target(); 182 target_col = compute_code_target();
185 { 183 {
186 int i; 184 int i;
187 185
188 for (i = 0; i < ps.p_l_follow; i++) 186 for (i = 0; i < ps.p_l_follow; i++)
189 if (ps.paren_indents[i] >= 0) 187 if (ps.paren_indents[i] >= 0)
190 ps.paren_indents[i] = -(ps.paren_indents[i] + target_col); 188 ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
191 } 189 }
192 cur_col = pad_output(cur_col, target_col); 190 cur_col = pad_output(cur_col, target_col);
193 for (p = s_code; p < e_code; p++) 191 for (p = s_code; p < e_code; p++)
194 if (*p == (char) 0200) 192 if (*p == (char) 0200)
195 output_int(target_col * 7); 193 output_int(target_col * 7);
196 else 194 else
197 output_char(*p); 195 output_char(*p);
198 cur_col = count_spaces(cur_col, s_code); 196 cur_col = count_spaces(cur_col, s_code);
199 } 197 }
200 if (s_com != e_com) { /* print comment, if any */ 198 if (s_com != e_com) { /* print comment, if any */
201 int target = ps.com_col; 199 int target = ps.com_col;
202 char *com_st = s_com; 200 char *com_st = s_com;
203 201
204 target += ps.comment_delta; 202 target += ps.comment_delta;
205 while (*com_st == '\t') /* consider original indentation in 203 while (*com_st == '\t') /* consider original indentation in
206 * case this is a box comment */ 204 * case this is a box comment */
207 com_st++, target += opt.tabsize; 205 com_st++, target += opt.tabsize;
208 while (target <= 0) 206 while (target <= 0)
209 if (*com_st == ' ') 207 if (*com_st == ' ')
210 target++, com_st++; 208 target++, com_st++;
211 else if (*com_st == '\t') { 209 else if (*com_st == '\t') {
212 target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1; 210 target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1;
213 com_st++; 211 com_st++;
214 } 212 } else
215 else 
216 target = 1; 213 target = 1;
217 if (cur_col > target) { /* if comment can't fit on this line, 214 if (cur_col > target) { /* if comment can't fit on this line,
218 * put it on next line */ 215 * put it on next line */
219 output_char('\n'); 216 output_char('\n');
220 cur_col = 1; 217 cur_col = 1;
221 ++ps.out_lines; 218 ++ps.out_lines;
222 } 219 }
223 while (e_com > com_st && isspace((unsigned char)e_com[-1])) 220 while (e_com > com_st && isspace((unsigned char)e_com[-1]))
224 e_com--; 221 e_com--;
225 (void)pad_output(cur_col, target); 222 (void)pad_output(cur_col, target);
226 output_range(com_st, e_com); 223 output_range(com_st, e_com);
227 ps.comment_delta = ps.n_comment_delta; 224 ps.comment_delta = ps.n_comment_delta;
228 ++ps.com_lines; /* count lines with comments */ 225 ++ps.com_lines; /* count lines with comments */
229 } 226 }
230 if (ps.use_ff) 227 if (ps.use_ff)
231 output_char('\014'); 228 output_char('\014');
232 else 229 else
233 output_char('\n'); 230 output_char('\n');
234 ++ps.out_lines; 231 ++ps.out_lines;
235 if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { 232 if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) {
236 prefix_blankline_requested = 1; 233 prefix_blankline_requested = 1;
237 ps.just_saw_decl = 0; 234 ps.just_saw_decl = 0;
238 } 235 } else
239 else 
240 prefix_blankline_requested = postfix_blankline_requested; 236 prefix_blankline_requested = postfix_blankline_requested;
241 postfix_blankline_requested = 0; 237 postfix_blankline_requested = 0;
242 } 238 }
243 239
244 /* keep blank lines after '//' comments */ 240 /* keep blank lines after '//' comments */
245 if (e_com - s_com > 1 && s_com[1] == '/') 241 if (e_com - s_com > 1 && s_com[1] == '/')
246 output_range(s_token, e_token); 242 output_range(s_token, e_token);
247 243
248 ps.decl_on_line = ps.in_decl; /* if we are in the middle of a 244 ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
249 * declaration, remember that fact for 245 * declaration, remember that fact for
250 * proper comment indentation */ 246 * proper comment indentation */
251 ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be 247 ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
252 * indented if we have not 248 * indented if we have not
253 * completed this stmt and if 249 * completed this stmt and if
254 * we are not in the middle of 250 * we are not in the middle of
255 * a declaration */ 251 * a declaration */
256 ps.use_ff = false; 252 ps.use_ff = false;
257 ps.dumped_decl_indent = 0; 253 ps.dumped_decl_indent = 0;
258 *(e_lab = s_lab) = '\0'; /* reset buffers */ 254 *(e_lab = s_lab) = '\0'; /* reset buffers */
259 *(e_code = s_code) = '\0'; 255 *(e_code = s_code) = '\0';
260 *(e_com = s_com = combuf + 1) = '\0'; 256 *(e_com = s_com = combuf + 1) = '\0';
261 ps.ind_level = ps.i_l_follow; 257 ps.ind_level = ps.i_l_follow;
262 ps.paren_level = ps.p_l_follow; 258 ps.paren_level = ps.p_l_follow;
263 if (ps.paren_level > 0) 259 if (ps.paren_level > 0)
264 paren_target = -ps.paren_indents[ps.paren_level - 1]; 260 paren_target = -ps.paren_indents[ps.paren_level - 1];
265 not_first_line = 1; 261 not_first_line = 1;
266} 262}
267 263
268int 264int
269compute_code_target(void) 265compute_code_target(void)
270{ 266{
271 int target_col = opt.ind_size * ps.ind_level + 1; 267 int target_col = opt.ind_size * ps.ind_level + 1;
272 268
273 if (ps.paren_level) 269 if (ps.paren_level) {
274 if (!opt.lineup_to_parens) 270 if (!opt.lineup_to_parens)
275 target_col += opt.continuation_indent * 271 target_col += opt.continuation_indent *
276 (2 * opt.continuation_indent == opt.ind_size ? 1 : ps.paren_level); 272 (2 * opt.continuation_indent == opt.ind_size ? 1 : ps.paren_level);
277 else if (opt.lineup_to_parens_always) 273 else if (opt.lineup_to_parens_always)
278 target_col = paren_target; 274 target_col = paren_target;
279 else { 275 else {
280 int w; 276 int w;
281 int t = paren_target; 277 int t = paren_target;
282 278
283 if ((w = count_spaces(t, s_code) - opt.max_col) > 0 279 if ((w = count_spaces(t, s_code) - opt.max_col) > 0
284 && count_spaces(target_col, s_code) <= opt.max_col) { 280 && count_spaces(target_col, s_code) <= opt.max_col) {
285 t -= w + 1; 281 t -= w + 1;
286 if (t > target_col) 282 if (t > target_col)
287 target_col = t; 283 target_col = t;
288 } 284 } else
289 else 
290 target_col = t; 285 target_col = t;
291 } 286 }
292 else if (ps.ind_stmt) 287 } else if (ps.ind_stmt)
293 target_col += opt.continuation_indent; 288 target_col += opt.continuation_indent;
294 return target_col; 289 return target_col;
295} 290}
296 291
297int 292int
298compute_label_target(void) 293compute_label_target(void)
299{ 294{
300 return 295 return
301 ps.pcase ? (int) (case_ind * opt.ind_size) + 1 296 ps.pcase ? (int) (case_ind * opt.ind_size) + 1
302 : *s_lab == '#' ? 1 297 : *s_lab == '#' ? 1
303 : opt.ind_size * (ps.ind_level - label_offset) + 1; 298 : opt.ind_size * (ps.ind_level - label_offset) + 1;
304} 299}
305 300
306 301
307/* 302/*
308 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois 303 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
309 * 304 *
310 * All rights reserved 305 * All rights reserved
311 * 306 *
312 * 307 *
313 * NAME: fill_buffer 308 * NAME: fill_buffer
314 * 309 *
315 * FUNCTION: Reads one block of input into input_buffer 310 * FUNCTION: Reads one block of input into input_buffer
316 * 311 *
317 * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A 312 * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
318 * Willcox of CAC Added check for switch back to partly full input 313 * Willcox of CAC Added check for switch back to partly full input
319 * buffer from temporary buffer 314 * buffer from temporary buffer
320 * 315 *
321 */ 316 */
322void 317void
323fill_buffer(void) 318fill_buffer(void)
324{ /* this routine reads stuff from the input */ 319{ /* this routine reads stuff from the input */
325 char *p; 320 char *p;
326 int i; 321 int i;
327 FILE *f = input; 322 FILE *f = input;
328 323
329 if (bp_save != NULL) { /* there is a partly filled input buffer left */ 324 if (bp_save != NULL) { /* there is a partly filled input buffer left */
330 buf_ptr = bp_save; /* do not read anything, just switch buffers */ 325 buf_ptr = bp_save; /* do not read anything, just switch buffers */
331 buf_end = be_save; 326 buf_end = be_save;
332 bp_save = be_save = NULL; 327 bp_save = be_save = NULL;
333 if (buf_ptr < buf_end) 328 if (buf_ptr < buf_end)
334 return; /* only return if there is really something in 329 return; /* only return if there is really something in
335 * this buffer */ 330 * this buffer */
336 } 331 }
337 for (p = in_buffer;;) { 332 for (p = in_buffer;;) {
338 if (p >= in_buffer_limit) { 333 if (p >= in_buffer_limit) {
339 int size = (in_buffer_limit - in_buffer) * 2 + 10; 334 int size = (in_buffer_limit - in_buffer) * 2 + 10;
340 int offset = p - in_buffer; 335 int offset = p - in_buffer;
341 in_buffer = realloc(in_buffer, size); 336 in_buffer = realloc(in_buffer, size);
342 if (in_buffer == NULL) 337 if (in_buffer == NULL)
343 errx(1, "input line too long"); 338 errx(1, "input line too long");
344 p = in_buffer + offset; 339 p = in_buffer + offset;
345 in_buffer_limit = in_buffer + size - 2; 340 in_buffer_limit = in_buffer + size - 2;
346 } 341 }
347 if ((i = getc(f)) == EOF) { 342 if ((i = getc(f)) == EOF) {
348 *p++ = ' '; 343 *p++ = ' ';
349 *p++ = '\n'; 344 *p++ = '\n';
350 had_eof = true; 345 had_eof = true;
351 break; 346 break;
352 } 347 }
353 if (i != '\0') 348 if (i != '\0')
354 *p++ = i; 349 *p++ = i;
355 if (i == '\n') 350 if (i == '\n')
356 break; 351 break;
357 } 352 }
358 buf_ptr = in_buffer; 353 buf_ptr = in_buffer;
359 buf_end = p; 354 buf_end = p;
360 if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { 355 if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') {
361 if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) 356 if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
362 fill_buffer(); /* flush indent error message */ 357 fill_buffer(); /* flush indent error message */
363 else { 358 else {
364 int com = 0; 359 int com = 0;
365 360
366 p = in_buffer; 361 p = in_buffer;
367 while (*p == ' ' || *p == '\t') 362 while (*p == ' ' || *p == '\t')
368 p++; 363 p++;
369 if (*p == '/' && p[1] == '*') { 364 if (*p == '/' && p[1] == '*') {
370 p += 2; 365 p += 2;
371 while (*p == ' ' || *p == '\t') 366 while (*p == ' ' || *p == '\t')
372 p++; 367 p++;
373 if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E' 368 if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
374 && p[4] == 'N' && p[5] == 'T') { 369 && p[4] == 'N' && p[5] == 'T') {
375 p += 6; 370 p += 6;
376 while (*p == ' ' || *p == '\t') 371 while (*p == ' ' || *p == '\t')
377 p++; 372 p++;
378 if (*p == '*') 373 if (*p == '*')
379 com = 1; 374 com = 1;
380 else if (*p == 'O') { 375 else if (*p == 'O') {
381 if (*++p == 'N') 376 if (*++p == 'N')
382 p++, com = 1; 377 p++, com = 1;
383 else if (*p == 'F' && *++p == 'F') 378 else if (*p == 'F' && *++p == 'F')
384 p++, com = 2; 379 p++, com = 2;
385 } 380 }
386 while (*p == ' ' || *p == '\t') 381 while (*p == ' ' || *p == '\t')
387 p++; 382 p++;
388 if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { 383 if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
389 if (s_com != e_com || s_lab != e_lab || s_code != e_code) 384 if (s_com != e_com || s_lab != e_lab || s_code != e_code)
390 dump_line(); 385 dump_line();
391 if (!(inhibit_formatting = com - 1)) { 386 if (!(inhibit_formatting = com - 1)) {
392 n_real_blanklines = 0; 387 n_real_blanklines = 0;
393 postfix_blankline_requested = 0; 388 postfix_blankline_requested = 0;
394 prefix_blankline_requested = 0; 389 prefix_blankline_requested = 0;
395 suppress_blanklines = 1; 390 suppress_blanklines = 1;
396 } 391 }
397 } 392 }
398 } 393 }
399 } 394 }
400 } 395 }
401 } 396 }
402 if (inhibit_formatting) { 397 if (inhibit_formatting) {
403 p = in_buffer; 398 p = in_buffer;
404 do { 399 do {
405 output_char(*p); 400 output_char(*p);
406 } while (*p++ != '\n'); 401 } while (*p++ != '\n');
407 } 402 }
408} 403}
409 404
410/* 405/*
411 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois 406 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
412 * 407 *
413 * All rights reserved 408 * All rights reserved
414 * 409 *
415 * 410 *
416 * NAME: pad_output 411 * NAME: pad_output
417 * 412 *
418 * FUNCTION: Writes tabs and spaces to move the current column up to the desired 413 * FUNCTION: Writes tabs and spaces to move the current column up to the desired
419 * position. 414 * position.
420 * 415 *
421 * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf. 416 * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
422 * 417 *
423 * PARAMETERS: current integer The current column target 418 * PARAMETERS: current integer The current column target
424 * nteger The desired column 419 * nteger The desired column
425 * 420 *
426 * RETURNS: Integer value of the new column. (If current >= target, no action is 421 * RETURNS: Integer value of the new column. (If current >= target, no action is
427 * taken, and current is returned. 422 * taken, and current is returned.
428 * 423 *
429 * GLOBALS: None 424 * GLOBALS: None
430 * 425 *
431 * CALLS: write (sys) 426 * CALLS: write (sys)
432 * 427 *
433 * CALLED BY: dump_line 428 * CALLED BY: dump_line
434 * 429 *
435 * HISTORY: initial coding November 1976 D A Willcox of CAC 430 * HISTORY: initial coding November 1976 D A Willcox of CAC
436 * 431 *
437 */ 432 */
438static int 433static int
439pad_output(int current, int target) 434pad_output(int current, int target)
440 /* writes tabs and blanks (if necessary) to 435 /* writes tabs and blanks (if necessary) to
441 * get the current output position up to the 436 * get the current output position up to the
442 * target column */ 437 * target column */
443 /* current: the current column value */ 438 /* current: the current column value */
444 /* target: position we want it at */ 439 /* target: position we want it at */
445{ 440{
446 int curr; /* internal column pointer */ 441 int curr; /* internal column pointer */
447 442
448 if (current >= target) 443 if (current >= target)
449 return current; /* line is already long enough */ 444 return current; /* line is already long enough */
450 curr = current; 445 curr = current;
451 if (opt.use_tabs) { 446 if (opt.use_tabs) {
452 int tcur; 447 int tcur;
453 448
454 while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) { 449 while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) {
455 output_char('\t'); 450 output_char('\t');
456 curr = tcur; 451 curr = tcur;
457 } 452 }
458 } 453 }
459 while (curr++ < target) 454 while (curr++ < target)
460 output_char(' '); /* pad with final blanks */ 455 output_char(' '); /* pad with final blanks */
461 456
462 return target; 457 return target;
463} 458}
464 459
465/* 460/*
466 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois 461 * Copyright (C) 1976 by the Board of Trustees of the University of Illinois
467 * 462 *
468 * All rights reserved 463 * All rights reserved
469 * 464 *
470 * 465 *
471 * NAME: count_spaces 466 * NAME: count_spaces
472 * 467 *
473 * FUNCTION: Find out where printing of a given string will leave the current 468 * FUNCTION: Find out where printing of a given string will leave the current
474 * character position on output. 469 * character position on output.
475 * 470 *
476 * ALGORITHM: Run thru input string and add appropriate values to current 471 * ALGORITHM: Run thru input string and add appropriate values to current
477 * position. 472 * position.
478 * 473 *
479 * RETURNS: Integer value of position after printing "buffer" starting in column 474 * RETURNS: Integer value of position after printing "buffer" starting in column
480 * "current". 475 * "current".
481 * 476 *
482 * HISTORY: initial coding November 1976 D A Willcox of CAC 477 * HISTORY: initial coding November 1976 D A Willcox of CAC
483 * 478 *
484 */ 479 */
485int 480int
486count_spaces_until(int cur, char *buffer, char *end) 481count_spaces_until(int cur, char *buffer, char *end)
487/* 482/*
488 * this routine figures out where the character position will be after 483 * this routine figures out where the character position will be after
489 * printing the text in buffer starting at column "current" 484 * printing the text in buffer starting at column "current"
490 */ 485 */
491{ 486{
492 char *buf; /* used to look thru buffer */ 487 char *buf; /* used to look thru buffer */
493 488
494 for (buf = buffer; *buf != '\0' && buf != end; ++buf) { 489 for (buf = buffer; *buf != '\0' && buf != end; ++buf) {
495 switch (*buf) { 490 switch (*buf) {
496 491
497 case '\n': 492 case '\n':
498 case 014: /* form feed */ 493 case 014: /* form feed */
499 cur = 1; 494 cur = 1;
500 break; 495 break;
501 496
502 case '\t': 497 case '\t':
503 cur = opt.tabsize * (1 + (cur - 1) / opt.tabsize) + 1; 498 cur = opt.tabsize * (1 + (cur - 1) / opt.tabsize) + 1;
504 break; 499 break;
505 500
506 case 010: /* backspace */ 501 case 010: /* backspace */
507 --cur; 502 --cur;
508 break; 503 break;
509 504
510 default: 505 default:
511 ++cur; 506 ++cur;
512 break; 507 break;
513 } /* end of switch */ 508 } /* end of switch */
514 } /* end of for loop */ 509 } /* end of for loop */
515 return cur; 510 return cur;
516} 511}
517 512
518int 513int
519count_spaces(int cur, char *buffer) 514count_spaces(int cur, char *buffer)
520{ 515{
521 return count_spaces_until(cur, buffer, NULL); 516 return count_spaces_until(cur, buffer, NULL);
522} 517}
523 518
524void 519void
525diag(int level, const char *msg, ...) 520diag(int level, const char *msg, ...)
526{ 521{
527 va_list ap; 522 va_list ap;
528 const char *s, *e; 523 const char *s, *e;
529 524
530 if (level) 525 if (level)
531 found_err = 1; 526 found_err = 1;
532 527
533 if (output == stdout) { 528 if (output == stdout) {
534 s = "/**INDENT** "; 529 s = "/**INDENT** ";
535 e = " */"; 530 e = " */";
536 } else { 531 } else {
537 s = e = ""; 532 s = e = "";
538 } 533 }
539 534
540 va_start(ap, msg); 535 va_start(ap, msg);
541 fprintf(stderr, "%s%s@%d: ", s, level == 0 ? "Warning" : "Error", line_no); 536 fprintf(stderr, "%s%s@%d: ", s, level == 0 ? "Warning" : "Error", line_no);
542 vfprintf(stderr, msg, ap); 537 vfprintf(stderr, msg, ap);
543 fprintf(stderr, "%s\n", e); 538 fprintf(stderr, "%s\n", e);
544 va_end(ap); 539 va_end(ap);
545} 540}

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

--- src/usr.bin/indent/lexi.c 2021/03/12 18:11:50 1.37
+++ src/usr.bin/indent/lexi.c 2021/03/12 23:10:18 1.38
@@ -1,733 +1,730 @@ @@ -1,733 +1,730 @@
1/* $NetBSD: lexi.c,v 1.37 2021/03/12 18:11:50 rillig Exp $ */ 1/* $NetBSD: lexi.c,v 1.38 2021/03/12 23:10:18 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.37 2021/03/12 18:11:50 rillig Exp $"); 49__RCSID("$NetBSD: lexi.c,v 1.38 2021/03/12 23:10:18 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
174/* Initialize constant transition table */ 174/* Initialize constant transition table */
175void 175void
176init_constant_tt(void) 176init_constant_tt(void)
177{ 177{
178 table['-'] = table['+']; 178 table['-'] = table['+'];
179 table['8'] = table['9']; 179 table['8'] = table['9'];
180 table['2'] = table['3'] = table['4'] = table['5'] = table['6'] = table['7']; 180 table['2'] = table['3'] = table['4'] = table['5'] = table['6'] = table['7'];
181 table['A'] = table['C'] = table['D'] = table['c'] = table['d'] = table['a']; 181 table['A'] = table['C'] = table['D'] = table['c'] = table['d'] = table['a'];
182 table['B'] = table['b']; 182 table['B'] = table['b'];
183 table['E'] = table['e']; 183 table['E'] = table['e'];
184 table['U'] = table['u']; 184 table['U'] = table['u'];
185 table['X'] = table['x']; 185 table['X'] = table['x'];
186 table['P'] = table['p']; 186 table['P'] = table['p'];
187 table['F'] = table['f']; 187 table['F'] = table['f'];
188} 188}
189 189
190static char 190static char
191inbuf_peek(void) 191inbuf_peek(void)
192{ 192{
193 return *buf_ptr; 193 return *buf_ptr;
194} 194}
195 195
196static void 196static void
197inbuf_skip(void) 197inbuf_skip(void)
198{ 198{
199 buf_ptr++; 199 buf_ptr++;
200 if (buf_ptr >= buf_end) 200 if (buf_ptr >= buf_end)
201 fill_buffer(); 201 fill_buffer();
202} 202}
203 203
204static char 204static char
205inbuf_next(void) 205inbuf_next(void)
206{ 206{
207 char ch = inbuf_peek(); 207 char ch = inbuf_peek();
208 inbuf_skip(); 208 inbuf_skip();
209 return ch; 209 return ch;
210} 210}
211 211
212static void 212static void
213check_size_token(size_t desired_size) 213check_size_token(size_t desired_size)
214{ 214{
215 if (e_token + (desired_size) < l_token) 215 if (e_token + (desired_size) < l_token)
216 return; 216 return;
217 217
218 size_t nsize = l_token - s_token + 400 + desired_size; 218 size_t nsize = l_token - s_token + 400 + desired_size;
219 size_t token_len = e_token - s_token; 219 size_t token_len = e_token - s_token;
220 tokenbuf = realloc(tokenbuf, nsize); 220 tokenbuf = realloc(tokenbuf, nsize);
221 if (tokenbuf == NULL) 221 if (tokenbuf == NULL)
222 err(1, NULL); 222 err(1, NULL);
223 e_token = tokenbuf + token_len + 1; 223 e_token = tokenbuf + token_len + 1;
224 l_token = tokenbuf + nsize - 5; 224 l_token = tokenbuf + nsize - 5;
225 s_token = tokenbuf + 1; 225 s_token = tokenbuf + 1;
226} 226}
227 227
228static int 228static int
229compare_templ_array(const void *key, const void *elem) 229compare_templ_array(const void *key, const void *elem)
230{ 230{
231 return strcmp(key, ((const struct templ *)elem)->rwd); 231 return strcmp(key, ((const struct templ *)elem)->rwd);
232} 232}
233 233
234static int 234static int
235compare_string_array(const void *key, const void *elem) 235compare_string_array(const void *key, const void *elem)
236{ 236{
237 return strcmp(key, *((const char *const *)elem)); 237 return strcmp(key, *((const char *const *)elem));
238} 238}
239 239
240#ifdef debug 240#ifdef debug
241const char * 241const char *
242token_type_name(token_type tk) 242token_type_name(token_type tk)
243{ 243{
244 static const char *const name[] = { 244 static const char *const name[] = {
245 "end_of_file", "newline", "lparen", "rparen", "unary_op", 245 "end_of_file", "newline", "lparen", "rparen", "unary_op",
246 "binary_op", "postfix_op", "question", "case_label", "colon", 246 "binary_op", "postfix_op", "question", "case_label", "colon",
247 "semicolon", "lbrace", "rbrace", "ident", "comma", 247 "semicolon", "lbrace", "rbrace", "ident", "comma",
248 "comment", "switch_expr", "preprocessing", "form_feed", "decl", 248 "comment", "switch_expr", "preprocessing", "form_feed", "decl",
249 "keyword_for_if_while", "keyword_do_else", 249 "keyword_for_if_while", "keyword_do_else",
250 "if_expr", "while_expr", "for_exprs", 250 "if_expr", "while_expr", "for_exprs",
251 "stmt", "stmt_list", "keyword_else", "keyword_do", "do_stmt", 251 "stmt", "stmt_list", "keyword_else", "keyword_do", "do_stmt",
252 "if_expr_stmt", "if_expr_stmt_else", "period", "string_prefix", 252 "if_expr_stmt", "if_expr_stmt_else", "period", "string_prefix",
253 "storage_class", "funcname", "type_def", "keyword_struct_union_enum" 253 "storage_class", "funcname", "type_def", "keyword_struct_union_enum"
254 }; 254 };
255 255
256 assert(0 <= tk && tk < sizeof name / sizeof name[0]); 256 assert(0 <= tk && tk < sizeof name / sizeof name[0]);
257 257
258 return name[tk]; 258 return name[tk];
259} 259}
260 260
261static void 261static void
262print_buf(const char *name, const char *s, const char *e) 262print_buf(const char *name, const char *s, const char *e)
263{ 263{
264 if (s == e) 264 if (s == e)
265 return; 265 return;
266 266
267 printf(" %s \"", name); 267 printf(" %s \"", name);
268 for (const char *p = s; p < e; p++) { 268 for (const char *p = s; p < e; p++) {
269 if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') 269 if (isprint((unsigned char)*p) && *p != '\\' && *p != '"')
270 printf("%c", *p); 270 printf("%c", *p);
271 else if (*p == '\n') 271 else if (*p == '\n')
272 printf("\\n"); 272 printf("\\n");
273 else if (*p == '\t') 273 else if (*p == '\t')
274 printf("\\t"); 274 printf("\\t");
275 else 275 else
276 printf("\\x%02x", *p); 276 printf("\\x%02x", *p);
277 } 277 }
278 printf("\""); 278 printf("\"");
279} 279}
280 280
281static token_type 281static token_type
282lexi_end(token_type code) 282lexi_end(token_type code)
283{ 283{
284 printf("in line %d, lexi returns '%s'", line_no, token_type_name(code)); 284 printf("in line %d, lexi returns '%s'", line_no, token_type_name(code));
285 print_buf("token", s_token, e_token); 285 print_buf("token", s_token, e_token);
286 print_buf("label", s_lab, e_lab); 286 print_buf("label", s_lab, e_lab);
287 print_buf("code", s_code, e_code); 287 print_buf("code", s_code, e_code);
288 print_buf("comment", s_com, e_com); 288 print_buf("comment", s_com, e_com);
289 printf("\n"); 289 printf("\n");
290 290
291 return code; 291 return code;
292} 292}
293#else 293#else
294# define lexi_end(tk) (tk) 294# define lexi_end(tk) (tk)
295#endif 295#endif
296 296
297token_type 297token_type
298lexi(struct parser_state *state) 298lexi(struct parser_state *state)
299{ 299{
300 int unary_delim; /* this is set to 1 if the current token 300 int unary_delim; /* this is set to 1 if the current token
301 * forces a following operator to be unary */ 301 * forces a following operator to be unary */
302 token_type code; /* internal code to be returned */ 302 token_type code; /* internal code to be returned */
303 char qchar; /* the delimiter character for a string */ 303 char qchar; /* the delimiter character for a string */
304 304
305 e_token = s_token; /* point to start of place to save token */ 305 e_token = s_token; /* point to start of place to save token */
306 unary_delim = false; 306 unary_delim = false;
307 state->col_1 = state->last_nl; /* tell world that this token started 307 state->col_1 = state->last_nl; /* tell world that this token started
308 * in column 1 iff the last thing 308 * in column 1 iff the last thing
309 * scanned was a newline */ 309 * scanned was a newline */
310 state->last_nl = false; 310 state->last_nl = false;
311 311
312 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ 312 while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
313 state->col_1 = false; /* leading blanks imply token is not in column 313 state->col_1 = false; /* leading blanks imply token is not in column
314 * 1 */ 314 * 1 */
315 inbuf_skip(); 315 inbuf_skip();
316 } 316 }
317 317
318 /* Scan an alphanumeric token */ 318 /* Scan an alphanumeric token */
319 if (isalnum((unsigned char)*buf_ptr) || 319 if (isalnum((unsigned char)*buf_ptr) ||
320 *buf_ptr == '_' || *buf_ptr == '$' || 320 *buf_ptr == '_' || *buf_ptr == '$' ||
321 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { 321 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
322 /* 322 /*
323 * we have a character or number 323 * we have a character or number
324 */ 324 */
325 struct templ *p; 325 struct templ *p;
326 326
327 if (isdigit((unsigned char)*buf_ptr) || 327 if (isdigit((unsigned char)*buf_ptr) ||
328 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { 328 (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
329 char s; 329 char s;
330 unsigned char i; 330 unsigned char i;
331 331
332 for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) { 332 for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) {
333 i = (unsigned char)*buf_ptr; 333 i = (unsigned char)*buf_ptr;
334 if (i >= nitems(table) || table[i] == NULL || 334 if (i >= nitems(table) || table[i] == NULL ||
335 table[i][s - 'A'] == ' ') { 335 table[i][s - 'A'] == ' ') {
336 s = table[0][s - 'A']; 336 s = table[0][s - 'A'];
337 break; 337 break;
338 } 338 }
339 s = table[i][s - 'A']; 339 s = table[i][s - 'A'];
340 check_size_token(1); 340 check_size_token(1);
341 *e_token++ = inbuf_next(); 341 *e_token++ = inbuf_next();
342 } 342 }
343 /* s now indicates the type: f(loating), i(integer), u(nknown) */ 343 /* s now indicates the type: f(loating), i(integer), u(nknown) */
344 } 344 } else {
345 else 
346 while (isalnum((unsigned char)*buf_ptr) || 345 while (isalnum((unsigned char)*buf_ptr) ||
347 *buf_ptr == '\\' || 346 *buf_ptr == '\\' ||
348 *buf_ptr == '_' || *buf_ptr == '$') { 347 *buf_ptr == '_' || *buf_ptr == '$') {
349 /* fill_buffer() terminates buffer with newline */ 348 /* fill_buffer() terminates buffer with newline */
350 if (*buf_ptr == '\\') { 349 if (*buf_ptr == '\\') {
351 if (buf_ptr[1] == '\n') { 350 if (buf_ptr[1] == '\n') {
352 buf_ptr += 2; 351 buf_ptr += 2;
353 if (buf_ptr >= buf_end) 352 if (buf_ptr >= buf_end)
354 fill_buffer(); 353 fill_buffer();
355 } else 354 } else
356 break; 355 break;
357 } 356 }
358 check_size_token(1); 357 check_size_token(1);
359 *e_token++ = inbuf_next(); 358 *e_token++ = inbuf_next();
360 } 359 }
 360 }
361 *e_token = '\0'; 361 *e_token = '\0';
362 362
363 if (s_token[0] == 'L' && s_token[1] == '\0' && 363 if (s_token[0] == 'L' && s_token[1] == '\0' &&
364 (*buf_ptr == '"' || *buf_ptr == '\'')) 364 (*buf_ptr == '"' || *buf_ptr == '\''))
365 return lexi_end(string_prefix); 365 return lexi_end(string_prefix);
366 366
367 while (*buf_ptr == ' ' || *buf_ptr == '\t') /* get rid of blanks */ 367 while (*buf_ptr == ' ' || *buf_ptr == '\t') /* get rid of blanks */
368 inbuf_next(); 368 inbuf_next();
369 state->keyword = rw_0; 369 state->keyword = rw_0;
370 if (state->last_token == keyword_struct_union_enum && 370 if (state->last_token == keyword_struct_union_enum &&
371 !state->p_l_follow) { 371 !state->p_l_follow) {
372 /* if last token was 'struct' and we're not in parentheses, then 372 /* if last token was 'struct' and we're not in parentheses, then
373 * this token should be treated as a declaration */ 373 * this token should be treated as a declaration */
374 state->last_u_d = true; 374 state->last_u_d = true;
375 return lexi_end(decl); 375 return lexi_end(decl);
376 } 376 }
377 /* 377 /*
378 * Operator after identifier is binary unless last token was 'struct' 378 * Operator after identifier is binary unless last token was 'struct'
379 */ 379 */
380 state->last_u_d = (state->last_token == keyword_struct_union_enum); 380 state->last_u_d = (state->last_token == keyword_struct_union_enum);
381 381
382 p = bsearch(s_token, specials, sizeof specials / sizeof specials[0], 382 p = bsearch(s_token, specials, sizeof specials / sizeof specials[0],
383 sizeof specials[0], compare_templ_array); 383 sizeof specials[0], compare_templ_array);
384 if (p == NULL) { /* not a special keyword... */ 384 if (p == NULL) { /* not a special keyword... */
385 char *u; 385 char *u;
386 386
387 /* ... so maybe a type_t or a typedef */ 387 /* ... so maybe a type_t or a typedef */
388 if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && 388 if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) &&
389 strcmp(u, "_t") == 0) || (typename_top >= 0 && 389 strcmp(u, "_t") == 0) || (typename_top >= 0 &&
390 bsearch(s_token, typenames, typename_top + 1, 390 bsearch(s_token, typenames, typename_top + 1,
391 sizeof typenames[0], compare_string_array))) { 391 sizeof typenames[0], compare_string_array))) {
392 state->keyword = rw_type; 392 state->keyword = rw_type;
393 state->last_u_d = true; 393 state->last_u_d = true;
394 goto found_typename; 394 goto found_typename;
395 } 395 }
396 } else { /* we have a keyword */ 396 } else { /* we have a keyword */
397 state->keyword = p->rwcode; 397 state->keyword = p->rwcode;
398 state->last_u_d = true; 398 state->last_u_d = true;
399 switch (p->rwcode) { 399 switch (p->rwcode) {
400 case rw_switch: 400 case rw_switch:
401 return lexi_end(switch_expr); 401 return lexi_end(switch_expr);
402 case rw_case_or_default: 402 case rw_case_or_default:
403 return lexi_end(case_label); 403 return lexi_end(case_label);
404 case rw_struct_or_union_or_enum: 404 case rw_struct_or_union_or_enum:
405 case rw_type: 405 case rw_type:
406 found_typename: 406 found_typename:
407 if (state->p_l_follow) { 407 if (state->p_l_follow) {
408 /* inside parens: cast, param list, offsetof or sizeof */ 408 /* inside parens: cast, param list, offsetof or sizeof */
409 state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; 409 state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask;
410 } 410 }
411 if (state->last_token == period || state->last_token == unary_op) { 411 if (state->last_token == period || state->last_token == unary_op) {
412 state->keyword = rw_0; 412 state->keyword = rw_0;
413 break; 413 break;
414 } 414 }
415 if (p != NULL && p->rwcode == rw_struct_or_union_or_enum) 415 if (p != NULL && p->rwcode == rw_struct_or_union_or_enum)
416 return lexi_end(keyword_struct_union_enum); 416 return lexi_end(keyword_struct_union_enum);
417 if (state->p_l_follow) 417 if (state->p_l_follow)
418 break; 418 break;
419 return lexi_end(decl); 419 return lexi_end(decl);
420 420
421 case rw_for_or_if_or_while: 421 case rw_for_or_if_or_while:
422 return lexi_end(keyword_for_if_while); 422 return lexi_end(keyword_for_if_while);
423 423
424 case rw_do_or_else: 424 case rw_do_or_else:
425 return lexi_end(keyword_do_else); 425 return lexi_end(keyword_do_else);
426 426
427 case rw_storage_class: 427 case rw_storage_class:
428 return lexi_end(storage_class); 428 return lexi_end(storage_class);
429 429
430 case rw_typedef: 430 case rw_typedef:
431 return lexi_end(type_def); 431 return lexi_end(type_def);
432 432
433 default: /* all others are treated like any other 433 default: /* all others are treated like any other
434 * identifier */ 434 * identifier */
435 return lexi_end(ident); 435 return lexi_end(ident);
436 } /* end of switch */ 436 } /* end of switch */
437 } /* end of if (found_it) */ 437 } /* end of if (found_it) */
438 if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && 438 if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 &&
439 state->in_parameter_declaration == 0 && state->block_init == 0) { 439 state->in_parameter_declaration == 0 && state->block_init == 0) {
440 char *tp = buf_ptr; 440 char *tp = buf_ptr;
441 while (tp < buf_end) 441 while (tp < buf_end)
442 if (*tp++ == ')' && (*tp == ';' || *tp == ',')) 442 if (*tp++ == ')' && (*tp == ';' || *tp == ','))
443 goto not_proc; 443 goto not_proc;
444 strncpy(state->procname, token, sizeof state->procname - 1); 444 strncpy(state->procname, token, sizeof state->procname - 1);
445 if (state->in_decl) 445 if (state->in_decl)
446 state->in_parameter_declaration = 1; 446 state->in_parameter_declaration = 1;
447 return lexi_end(funcname); 447 return lexi_end(funcname);
448 not_proc:; 448 not_proc:;
449 } 449 }
450 /* 450 /*
451 * The following hack attempts to guess whether or not the current 451 * The following hack attempts to guess whether or not the current
452 * token is in fact a declaration keyword -- one that has been 452 * token is in fact a declaration keyword -- one that has been
453 * typedefd 453 * typedefd
454 */ 454 */
455 else if (!state->p_l_follow && !state->block_init && 455 else if (!state->p_l_follow && !state->block_init &&
456 !state->in_stmt && 456 !state->in_stmt &&
457 ((*buf_ptr == '*' && buf_ptr[1] != '=') || 457 ((*buf_ptr == '*' && buf_ptr[1] != '=') ||
458 isalpha((unsigned char)*buf_ptr)) && 458 isalpha((unsigned char)*buf_ptr)) &&
459 (state->last_token == semicolon || state->last_token == lbrace || 459 (state->last_token == semicolon || state->last_token == lbrace ||
460 state->last_token == rbrace)) { 460 state->last_token == rbrace)) {
461 state->keyword = rw_type; 461 state->keyword = rw_type;
462 state->last_u_d = true; 462 state->last_u_d = true;
463 return lexi_end(decl); 463 return lexi_end(decl);
464 } 464 }
465 if (state->last_token == decl) /* if this is a declared variable, 465 if (state->last_token == decl) /* if this is a declared variable,
466 * then following sign is unary */ 466 * then following sign is unary */
467 state->last_u_d = true; /* will make "int a -1" work */ 467 state->last_u_d = true; /* will make "int a -1" work */
468 return lexi_end(ident); /* the ident is not in the list */ 468 return lexi_end(ident); /* the ident is not in the list */
469 } /* end of procesing for alpanum character */ 469 } /* end of procesing for alpanum character */
470 470
471 /* Scan a non-alphanumeric token */ 471 /* Scan a non-alphanumeric token */
472 472
473 check_size_token(3); /* things like "<<=" */ 473 check_size_token(3); /* things like "<<=" */
474 *e_token++ = inbuf_next(); /* if it is only a one-character token, it is 474 *e_token++ = inbuf_next(); /* if it is only a one-character token, it is
475 * moved here */ 475 * moved here */
476 *e_token = '\0'; 476 *e_token = '\0';
477 477
478 switch (*token) { 478 switch (*token) {
479 case '\n': 479 case '\n':
480 unary_delim = state->last_u_d; 480 unary_delim = state->last_u_d;
481 state->last_nl = true; /* remember that we just had a newline */ 481 state->last_nl = true; /* remember that we just had a newline */
482 code = (had_eof ? end_of_file : newline); 482 code = (had_eof ? end_of_file : newline);
483 483
484 /* 484 /*
485 * if data has been exhausted, the newline is a dummy, and we should 485 * if data has been exhausted, the newline is a dummy, and we should
486 * return code to stop 486 * return code to stop
487 */ 487 */
488 break; 488 break;
489 489
490 case '\'': /* start of quoted character */ 490 case '\'': /* start of quoted character */
491 case '"': /* start of string */ 491 case '"': /* start of string */
492 qchar = *token; 492 qchar = *token;
493 do { /* copy the string */ 493 do { /* copy the string */
494 while (1) { /* move one character or [/<char>]<char> */ 494 while (1) { /* move one character or [/<char>]<char> */
495 if (*buf_ptr == '\n') { 495 if (*buf_ptr == '\n') {
496 diag(1, "Unterminated literal"); 496 diag(1, "Unterminated literal");
497 goto stop_lit; 497 goto stop_lit;
498 } 498 }
499 check_size_token(2); 499 check_size_token(2);
500 *e_token = inbuf_next(); 500 *e_token = inbuf_next();
501 if (*e_token == '\\') { /* if escape, copy extra char */ 501 if (*e_token == '\\') { /* if escape, copy extra char */
502 if (*buf_ptr == '\n') /* check for escaped newline */ 502 if (*buf_ptr == '\n') /* check for escaped newline */
503 ++line_no; 503 ++line_no;
504 *++e_token = inbuf_next(); 504 *++e_token = inbuf_next();
505 ++e_token; /* we must increment this again because we 505 ++e_token; /* we must increment this again because we
506 * copied two chars */ 506 * copied two chars */
507 } 507 } else
508 else 
509 break; /* we copied one character */ 508 break; /* we copied one character */
510 } /* end of while (1) */ 509 } /* end of while (1) */
511 } while (*e_token++ != qchar); 510 } while (*e_token++ != qchar);
512stop_lit: 511stop_lit:
513 code = ident; 512 code = ident;
514 break; 513 break;
515 514
516 case ('('): 515 case ('('):
517 case ('['): 516 case ('['):
518 unary_delim = true; 517 unary_delim = true;
519 code = lparen; 518 code = lparen;
520 break; 519 break;
521 520
522 case (')'): 521 case (')'):
523 case (']'): 522 case (']'):
524 code = rparen; 523 code = rparen;
525 break; 524 break;
526 525
527 case '#': 526 case '#':
528 unary_delim = state->last_u_d; 527 unary_delim = state->last_u_d;
529 code = preprocessing; 528 code = preprocessing;
530 break; 529 break;
531 530
532 case '?': 531 case '?':
533 unary_delim = true; 532 unary_delim = true;
534 code = question; 533 code = question;
535 break; 534 break;
536 535
537 case (':'): 536 case (':'):
538 code = colon; 537 code = colon;
539 unary_delim = true; 538 unary_delim = true;
540 break; 539 break;
541 540
542 case (';'): 541 case (';'):
543 unary_delim = true; 542 unary_delim = true;
544 code = semicolon; 543 code = semicolon;
545 break; 544 break;
546 545
547 case ('{'): 546 case ('{'):
548 unary_delim = true; 547 unary_delim = true;
549 548
550 /* 549 /*
551 * if (state->in_or_st) state->block_init = 1; 550 * if (state->in_or_st) state->block_init = 1;
552 */ 551 */
553 /* ? code = state->block_init ? lparen : lbrace; */ 552 /* ? code = state->block_init ? lparen : lbrace; */
554 code = lbrace; 553 code = lbrace;
555 break; 554 break;
556 555
557 case ('}'): 556 case ('}'):
558 unary_delim = true; 557 unary_delim = true;
559 /* ? code = state->block_init ? rparen : rbrace; */ 558 /* ? code = state->block_init ? rparen : rbrace; */
560 code = rbrace; 559 code = rbrace;
561 break; 560 break;
562 561
563 case 014: /* a form feed */ 562 case 014: /* a form feed */
564 unary_delim = state->last_u_d; 563 unary_delim = state->last_u_d;
565 state->last_nl = true; /* remember this so we can set 'state->col_1' 564 state->last_nl = true; /* remember this so we can set 'state->col_1'
566 * right */ 565 * right */
567 code = form_feed; 566 code = form_feed;
568 break; 567 break;
569 568
570 case (','): 569 case (','):
571 unary_delim = true; 570 unary_delim = true;
572 code = comma; 571 code = comma;
573 break; 572 break;
574 573
575 case '.': 574 case '.':
576 unary_delim = false; 575 unary_delim = false;
577 code = period; 576 code = period;
578 break; 577 break;
579 578
580 case '-': 579 case '-':
581 case '+': /* check for -, +, --, ++ */ 580 case '+': /* check for -, +, --, ++ */
582 code = (state->last_u_d ? unary_op : binary_op); 581 code = (state->last_u_d ? unary_op : binary_op);
583 unary_delim = true; 582 unary_delim = true;
584 583
585 if (*buf_ptr == token[0]) { 584 if (*buf_ptr == token[0]) {
586 /* check for doubled character */ 585 /* check for doubled character */
587 *e_token++ = *buf_ptr++; 586 *e_token++ = *buf_ptr++;
588 /* buffer overflow will be checked at end of loop */ 587 /* buffer overflow will be checked at end of loop */
589 if (state->last_token == ident || state->last_token == rparen) { 588 if (state->last_token == ident || state->last_token == rparen) {
590 code = (state->last_u_d ? unary_op : postfix_op); 589 code = (state->last_u_d ? unary_op : postfix_op);
591 /* check for following ++ or -- */ 590 /* check for following ++ or -- */
592 unary_delim = false; 591 unary_delim = false;
593 } 592 }
594 } 593 } else if (*buf_ptr == '=')
595 else if (*buf_ptr == '=') 
596 /* check for operator += */ 594 /* check for operator += */
597 *e_token++ = *buf_ptr++; 595 *e_token++ = *buf_ptr++;
598 else if (*buf_ptr == '>') { 596 else if (*buf_ptr == '>') {
599 /* check for operator -> */ 597 /* check for operator -> */
600 *e_token++ = *buf_ptr++; 598 *e_token++ = *buf_ptr++;
601 unary_delim = false; 599 unary_delim = false;
602 code = unary_op; 600 code = unary_op;
603 state->want_blank = false; 601 state->want_blank = false;
604 } 602 }
605 break; /* buffer overflow will be checked at end of 603 break; /* buffer overflow will be checked at end of
606 * switch */ 604 * switch */
607 605
608 case '=': 606 case '=':
609 if (state->in_or_st) 607 if (state->in_or_st)
610 state->block_init = 1; 608 state->block_init = 1;
611 if (*buf_ptr == '=') { /* == */ 609 if (*buf_ptr == '=') { /* == */
612 *e_token++ = '='; /* Flip =+ to += */ 610 *e_token++ = '='; /* Flip =+ to += */
613 buf_ptr++; 611 buf_ptr++;
614 *e_token = 0; 612 *e_token = 0;
615 } 613 }
616 code = binary_op; 614 code = binary_op;
617 unary_delim = true; 615 unary_delim = true;
618 break; 616 break;
619 /* can drop thru!!! */ 617 /* can drop thru!!! */
620 618
621 case '>': 619 case '>':
622 case '<': 620 case '<':
623 case '!': /* ops like <, <<, <=, !=, etc */ 621 case '!': /* ops like <, <<, <=, !=, etc */
624 if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') 622 if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=')
625 *e_token++ = inbuf_next(); 623 *e_token++ = inbuf_next();
626 if (*buf_ptr == '=') 624 if (*buf_ptr == '=')
627 *e_token++ = *buf_ptr++; 625 *e_token++ = *buf_ptr++;
628 code = (state->last_u_d ? unary_op : binary_op); 626 code = (state->last_u_d ? unary_op : binary_op);
629 unary_delim = true; 627 unary_delim = true;
630 break; 628 break;
631 629
632 case '*': 630 case '*':
633 unary_delim = true; 631 unary_delim = true;
634 if (!state->last_u_d) { 632 if (!state->last_u_d) {
635 if (*buf_ptr == '=') 633 if (*buf_ptr == '=')
636 *e_token++ = *buf_ptr++; 634 *e_token++ = *buf_ptr++;
637 code = binary_op; 635 code = binary_op;
638 break; 636 break;
639 } 637 }
640 while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { 638 while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) {
641 if (*buf_ptr == '*') { 639 if (*buf_ptr == '*') {
642 check_size_token(1); 640 check_size_token(1);
643 *e_token++ = *buf_ptr; 641 *e_token++ = *buf_ptr;
644 } 642 }
645 inbuf_skip(); 643 inbuf_skip();
646 } 644 }
647 if (ps.in_decl) { 645 if (ps.in_decl) {
648 char *tp = buf_ptr; 646 char *tp = buf_ptr;
649 647
650 while (isalpha((unsigned char)*tp) || 648 while (isalpha((unsigned char)*tp) ||
651 isspace((unsigned char)*tp)) { 649 isspace((unsigned char)*tp)) {
652 if (++tp >= buf_end) 650 if (++tp >= buf_end)
653 fill_buffer(); 651 fill_buffer();
654 } 652 }
655 if (*tp == '(') 653 if (*tp == '(')
656 ps.procname[0] = ' '; 654 ps.procname[0] = ' ';
657 } 655 }
658 code = unary_op; 656 code = unary_op;
659 break; 657 break;
660 658
661 default: 659 default:
662 if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { 660 if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) {
663 /* it is start of comment */ 661 /* it is start of comment */
664 *e_token++ = inbuf_next(); 662 *e_token++ = inbuf_next();
665 663
666 code = comment; 664 code = comment;
667 unary_delim = state->last_u_d; 665 unary_delim = state->last_u_d;
668 break; 666 break;
669 } 667 }
670 while (e_token[-1] == *buf_ptr || *buf_ptr == '=') { 668 while (e_token[-1] == *buf_ptr || *buf_ptr == '=') {
671 /* 669 /*
672 * handle ||, &&, etc, and also things as in int *****i 670 * handle ||, &&, etc, and also things as in int *****i
673 */ 671 */
674 check_size_token(1); 672 check_size_token(1);
675 *e_token++ = inbuf_next(); 673 *e_token++ = inbuf_next();
676 } 674 }
677 code = (state->last_u_d ? unary_op : binary_op); 675 code = (state->last_u_d ? unary_op : binary_op);
678 unary_delim = true; 676 unary_delim = true;
679 677
680 678
681 } /* end of switch */ 679 } /* end of switch */
682 if (buf_ptr >= buf_end) /* check for input buffer empty */ 680 if (buf_ptr >= buf_end) /* check for input buffer empty */
683 fill_buffer(); 681 fill_buffer();
684 state->last_u_d = unary_delim; 682 state->last_u_d = unary_delim;
685 check_size_token(1); 683 check_size_token(1);
686 *e_token = '\0'; /* null terminate the token */ 684 *e_token = '\0'; /* null terminate the token */
687 return lexi_end(code); 685 return lexi_end(code);
688} 686}
689 687
690void 688void
691alloc_typenames(void) 689alloc_typenames(void)
692{ 690{
693 691
694 typenames = malloc(sizeof(typenames[0]) * (typename_count = 16)); 692 typenames = malloc(sizeof(typenames[0]) * (typename_count = 16));
695 if (typenames == NULL) 693 if (typenames == NULL)
696 err(1, NULL); 694 err(1, NULL);
697} 695}
698 696
699void 697void
700add_typename(const char *key) 698add_typename(const char *key)
701{ 699{
702 int comparison; 700 int comparison;
703 const char *copy; 701 const char *copy;
704 702
705 if (typename_top + 1 >= typename_count) { 703 if (typename_top + 1 >= typename_count) {
706 typenames = realloc((void *)typenames, 704 typenames = realloc((void *)typenames,
707 sizeof(typenames[0]) * (typename_count *= 2)); 705 sizeof(typenames[0]) * (typename_count *= 2));
708 if (typenames == NULL) 706 if (typenames == NULL)
709 err(1, NULL); 707 err(1, NULL);
710 } 708 }
711 if (typename_top == -1) 709 if (typename_top == -1)
712 typenames[++typename_top] = copy = strdup(key); 710 typenames[++typename_top] = copy = strdup(key);
713 else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { 711 else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) {
714 /* take advantage of sorted input */ 712 /* take advantage of sorted input */
715 if (comparison == 0) /* remove duplicates */ 713 if (comparison == 0) /* remove duplicates */
716 return; 714 return;
717 typenames[++typename_top] = copy = strdup(key); 715 typenames[++typename_top] = copy = strdup(key);
718 } 716 } else {
719 else { 
720 int p; 717 int p;
721 718
722 for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) 719 for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++)
723 /* find place for the new key */; 720 /* find place for the new key */;
724 if (comparison == 0) /* remove duplicates */ 721 if (comparison == 0) /* remove duplicates */
725 return; 722 return;
726 memmove(&typenames[p + 1], &typenames[p], 723 memmove(&typenames[p + 1], &typenames[p],
727 sizeof(typenames[0]) * (++typename_top - p)); 724 sizeof(typenames[0]) * (++typename_top - p));
728 typenames[p] = copy = strdup(key); 725 typenames[p] = copy = strdup(key);
729 } 726 }
730 727
731 if (copy == NULL) 728 if (copy == NULL)
732 err(1, NULL); 729 err(1, NULL);
733} 730}

cvs diff -r1.17 -r1.18 src/usr.bin/indent/parse.c (switch to unified diff)

--- src/usr.bin/indent/parse.c 2021/03/09 19:14:39 1.17
+++ src/usr.bin/indent/parse.c 2021/03/12 23:10:18 1.18
@@ -1,309 +1,307 @@ @@ -1,309 +1,307 @@
1/* $NetBSD: parse.c,v 1.17 2021/03/09 19:14:39 rillig Exp $ */ 1/* $NetBSD: parse.c,v 1.18 2021/03/12 23:10:18 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[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93"; 42static char sccsid[] = "@(#)parse.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("$FreeBSD$"); 49__RCSID("$FreeBSD$");
50#else 50#else
51__FBSDID("$FreeBSD: head/usr.bin/indent/parse.c 337651 2018-08-11 19:20:06Z pstef $"); 51__FBSDID("$FreeBSD: head/usr.bin/indent/parse.c 337651 2018-08-11 19:20:06Z pstef $");
52#endif 52#endif
53#endif 53#endif
54 54
55#include <err.h> 55#include <err.h>
56#include <stdio.h> 56#include <stdio.h>
57 57
58#include "indent.h" 58#include "indent.h"
59 59
60static void reduce(void); 60static void reduce(void);
61 61
62void 62void
63parse(token_type tk) /* tk: the code for the construct scanned */ 63parse(token_type tk) /* tk: the code for the construct scanned */
64{ 64{
65 int i; 65 int i;
66 66
67#ifdef debug 67#ifdef debug
68 printf("parse token: '%s' \"%s\"\n", token_type_name(tk), token); 68 printf("parse token: '%s' \"%s\"\n", token_type_name(tk), token);
69#endif 69#endif
70 70
71 while (ps.p_stack[ps.tos] == if_expr_stmt && tk != keyword_else) { 71 while (ps.p_stack[ps.tos] == if_expr_stmt && tk != keyword_else) {
72 /* true if we have an if without an else */ 72 /* true if we have an if without an else */
73 ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt 73 ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt
74 * reduction */ 74 * reduction */
75 reduce(); /* see if this allows any reduction */ 75 reduce(); /* see if this allows any reduction */
76 } 76 }
77 77
78 78
79 switch (tk) { /* go on and figure out what to do with the 79 switch (tk) { /* go on and figure out what to do with the
80 * input */ 80 * input */
81 81
82 case decl: /* scanned a declaration word */ 82 case decl: /* scanned a declaration word */
83 ps.search_brace = opt.btype_2; 83 ps.search_brace = opt.btype_2;
84 /* indicate that following brace should be on same line */ 84 /* indicate that following brace should be on same line */
85 if (ps.p_stack[ps.tos] != decl) { /* only put one declaration 85 if (ps.p_stack[ps.tos] != decl) { /* only put one declaration
86 * onto stack */ 86 * onto stack */
87 break_comma = true; /* while in declaration, newline should be 87 break_comma = true; /* while in declaration, newline should be
88 * forced after comma */ 88 * forced after comma */
89 ps.p_stack[++ps.tos] = decl; 89 ps.p_stack[++ps.tos] = decl;
90 ps.il[ps.tos] = ps.i_l_follow; 90 ps.il[ps.tos] = ps.i_l_follow;
91 91
92 if (opt.ljust_decl) {/* only do if we want left justified 92 if (opt.ljust_decl) {/* only do if we want left justified
93 * declarations */ 93 * declarations */
94 ps.ind_level = 0; 94 ps.ind_level = 0;
95 for (i = ps.tos - 1; i > 0; --i) 95 for (i = ps.tos - 1; i > 0; --i)
96 if (ps.p_stack[i] == decl) 96 if (ps.p_stack[i] == decl)
97 ++ps.ind_level; /* indentation is number of 97 ++ps.ind_level; /* indentation is number of
98 * declaration levels deep we are */ 98 * declaration levels deep we are */
99 ps.i_l_follow = ps.ind_level; 99 ps.i_l_follow = ps.ind_level;
100 } 100 }
101 } 101 }
102 break; 102 break;
103 103
104 case if_expr: /* 'if' '(' <expr> ')' */ 104 case if_expr: /* 'if' '(' <expr> ')' */
105 if (ps.p_stack[ps.tos] == if_expr_stmt_else && opt.else_if) { 105 if (ps.p_stack[ps.tos] == if_expr_stmt_else && opt.else_if) {
106 /* 106 /*
107 * Note that the stack pointer here is decremented, effectively 107 * Note that the stack pointer here is decremented, effectively
108 * reducing "else if" to "if". This saves a lot of stack space 108 * reducing "else if" to "if". This saves a lot of stack space
109 * in case of a long "if-else-if ... else-if" sequence. 109 * in case of a long "if-else-if ... else-if" sequence.
110 */ 110 */
111 ps.i_l_follow = ps.il[ps.tos--]; 111 ps.i_l_follow = ps.il[ps.tos--];
112 } 112 }
113 /* the rest is the same as for keyword_do and for_exprs */ 113 /* the rest is the same as for keyword_do and for_exprs */
114 /* FALLTHROUGH */ 114 /* FALLTHROUGH */
115 case keyword_do: /* 'do' */ 115 case keyword_do: /* 'do' */
116 case for_exprs: /* 'for' (...) */ 116 case for_exprs: /* 'for' (...) */
117 ps.p_stack[++ps.tos] = tk; 117 ps.p_stack[++ps.tos] = tk;
118 ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; 118 ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
119 ++ps.i_l_follow; /* subsequent statements should be indented 1 */ 119 ++ps.i_l_follow; /* subsequent statements should be indented 1 */
120 ps.search_brace = opt.btype_2; 120 ps.search_brace = opt.btype_2;
121 break; 121 break;
122 122
123 case lbrace: /* scanned { */ 123 case lbrace: /* scanned { */
124 break_comma = false; /* don't break comma in an initial list */ 124 break_comma = false; /* don't break comma in an initial list */
125 if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl 125 if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
126 || ps.p_stack[ps.tos] == stmt_list) 126 || ps.p_stack[ps.tos] == stmt_list)
127 ++ps.i_l_follow; /* it is a random, isolated stmt group or a 127 ++ps.i_l_follow; /* it is a random, isolated stmt group or a
128 * declaration */ 128 * declaration */
129 else { 129 else {
130 if (s_code == e_code) { 130 if (s_code == e_code) {
131 /* 131 /*
132 * only do this if there is nothing on the line 132 * only do this if there is nothing on the line
133 */ 133 */
134 --ps.ind_level; 134 --ps.ind_level;
135 /* 135 /*
136 * it is a group as part of a while, for, etc. 136 * it is a group as part of a while, for, etc.
137 */ 137 */
138 if (ps.p_stack[ps.tos] == switch_expr && opt.case_indent >= 1) 138 if (ps.p_stack[ps.tos] == switch_expr && opt.case_indent >= 1)
139 --ps.ind_level; 139 --ps.ind_level;
140 /* 140 /*
141 * for a switch, brace should be two levels out from the code 141 * for a switch, brace should be two levels out from the code
142 */ 142 */
143 } 143 }
144 } 144 }
145 145
146 ps.p_stack[++ps.tos] = lbrace; 146 ps.p_stack[++ps.tos] = lbrace;
147 ps.il[ps.tos] = ps.ind_level; 147 ps.il[ps.tos] = ps.ind_level;
148 ps.p_stack[++ps.tos] = stmt; 148 ps.p_stack[++ps.tos] = stmt;
149 /* allow null stmt between braces */ 149 /* allow null stmt between braces */
150 ps.il[ps.tos] = ps.i_l_follow; 150 ps.il[ps.tos] = ps.i_l_follow;
151 break; 151 break;
152 152
153 case while_expr: /* 'while' '(' <expr> ')' */ 153 case while_expr: /* 'while' '(' <expr> ')' */
154 if (ps.p_stack[ps.tos] == do_stmt) { 154 if (ps.p_stack[ps.tos] == do_stmt) {
155 /* it is matched with do stmt */ 155 /* it is matched with do stmt */
156 ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; 156 ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
157 ps.p_stack[++ps.tos] = while_expr; 157 ps.p_stack[++ps.tos] = while_expr;
158 ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; 158 ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
159 } 159 } else { /* it is a while loop */
160 else { /* it is a while loop */ 
161 ps.p_stack[++ps.tos] = while_expr; 160 ps.p_stack[++ps.tos] = while_expr;
162 ps.il[ps.tos] = ps.i_l_follow; 161 ps.il[ps.tos] = ps.i_l_follow;
163 ++ps.i_l_follow; 162 ++ps.i_l_follow;
164 ps.search_brace = opt.btype_2; 163 ps.search_brace = opt.btype_2;
165 } 164 }
166 165
167 break; 166 break;
168 167
169 case keyword_else: 168 case keyword_else:
170 if (ps.p_stack[ps.tos] != if_expr_stmt) 169 if (ps.p_stack[ps.tos] != if_expr_stmt)
171 diag(1, "Unmatched 'else'"); 170 diag(1, "Unmatched 'else'");
172 else { 171 else {
173 ps.ind_level = ps.il[ps.tos]; /* indentation for else should 172 ps.ind_level = ps.il[ps.tos]; /* indentation for else should
174 * be same as for if */ 173 * be same as for if */
175 ps.i_l_follow = ps.ind_level + 1; /* everything following should 174 ps.i_l_follow = ps.ind_level + 1; /* everything following should
176 * be in 1 level */ 175 * be in 1 level */
177 ps.p_stack[ps.tos] = if_expr_stmt_else; 176 ps.p_stack[ps.tos] = if_expr_stmt_else;
178 /* remember if with else */ 177 /* remember if with else */
179 ps.search_brace = opt.btype_2 | opt.else_if; 178 ps.search_brace = opt.btype_2 | opt.else_if;
180 } 179 }
181 break; 180 break;
182 181
183 case rbrace: /* scanned a } */ 182 case rbrace: /* scanned a } */
184 /* stack should have <lbrace> <stmt> or <lbrace> <stmt_list> */ 183 /* stack should have <lbrace> <stmt> or <lbrace> <stmt_list> */
185 if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) { 184 if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) {
186 ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; 185 ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
187 ps.p_stack[ps.tos] = stmt; 186 ps.p_stack[ps.tos] = stmt;
188 } 187 } else
189 else 
190 diag(1, "Statement nesting error"); 188 diag(1, "Statement nesting error");
191 break; 189 break;
192 190
193 case switch_expr: /* had switch (...) */ 191 case switch_expr: /* had switch (...) */
194 ps.p_stack[++ps.tos] = switch_expr; 192 ps.p_stack[++ps.tos] = switch_expr;
195 ps.cstk[ps.tos] = case_ind; 193 ps.cstk[ps.tos] = case_ind;
196 /* save current case indent level */ 194 /* save current case indent level */
197 ps.il[ps.tos] = ps.i_l_follow; 195 ps.il[ps.tos] = ps.i_l_follow;
198 case_ind = ps.i_l_follow + opt.case_indent; /* cases should be one 196 case_ind = ps.i_l_follow + opt.case_indent; /* cases should be one
199 * level down from 197 * level down from
200 * switch */ 198 * switch */
201 ps.i_l_follow += opt.case_indent + 1; /* statements should be two 199 ps.i_l_follow += opt.case_indent + 1; /* statements should be two
202 * levels in */ 200 * levels in */
203 ps.search_brace = opt.btype_2; 201 ps.search_brace = opt.btype_2;
204 break; 202 break;
205 203
206 case semicolon: /* this indicates a simple stmt */ 204 case semicolon: /* this indicates a simple stmt */
207 break_comma = false; /* turn off flag to break after commas in a 205 break_comma = false; /* turn off flag to break after commas in a
208 * declaration */ 206 * declaration */
209 ps.p_stack[++ps.tos] = stmt; 207 ps.p_stack[++ps.tos] = stmt;
210 ps.il[ps.tos] = ps.ind_level; 208 ps.il[ps.tos] = ps.ind_level;
211 break; 209 break;
212 210
213 default: /* this is an error */ 211 default: /* this is an error */
214 diag(1, "Unknown code to parser"); 212 diag(1, "Unknown code to parser");
215 return; 213 return;
216 214
217 215
218 } /* end of switch */ 216 } /* end of switch */
219 217
220 if (ps.tos >= STACKSIZE - 1) 218 if (ps.tos >= STACKSIZE - 1)
221 errx(1, "Parser stack overflow"); 219 errx(1, "Parser stack overflow");
222 220
223 reduce(); /* see if any reduction can be done */ 221 reduce(); /* see if any reduction can be done */
224 222
225#ifdef debug 223#ifdef debug
226 printf("parse stack:"); 224 printf("parse stack:");
227 for (i = 1; i <= ps.tos; ++i) 225 for (i = 1; i <= ps.tos; ++i)
228 printf(" ('%s' at %d)", token_type_name(ps.p_stack[i]), ps.il[i]); 226 printf(" ('%s' at %d)", token_type_name(ps.p_stack[i]), ps.il[i]);
229 if (ps.tos == 0) 227 if (ps.tos == 0)
230 printf(" empty"); 228 printf(" empty");
231 printf("\n"); 229 printf("\n");
232#endif 230#endif
233} 231}
234 232
235/*----------------------------------------------*\ 233/*----------------------------------------------*\
236| REDUCTION PHASE | 234| REDUCTION PHASE |
237\*----------------------------------------------*/ 235\*----------------------------------------------*/
238 236
239/* 237/*
240 * Try to combine the statement on the top of the parse stack with the symbol 238 * Try to combine the statement on the top of the parse stack with the symbol
241 * directly below it, replacing these two symbols with a single symbol. 239 * directly below it, replacing these two symbols with a single symbol.
242 */ 240 */
243static int 241static int
244reduce_stmt(void) 242reduce_stmt(void)
245{ 243{
246 switch (ps.p_stack[ps.tos - 1]) { 244 switch (ps.p_stack[ps.tos - 1]) {
247 245
248 case stmt: /* stmt stmt */ 246 case stmt: /* stmt stmt */
249 case stmt_list: /* stmt_list stmt */ 247 case stmt_list: /* stmt_list stmt */
250 ps.p_stack[--ps.tos] = stmt_list; 248 ps.p_stack[--ps.tos] = stmt_list;
251 return true; 249 return true;
252 250
253 case keyword_do: /* 'do' <stmt> */ 251 case keyword_do: /* 'do' <stmt> */
254 ps.p_stack[--ps.tos] = do_stmt; 252 ps.p_stack[--ps.tos] = do_stmt;
255 ps.i_l_follow = ps.il[ps.tos]; 253 ps.i_l_follow = ps.il[ps.tos];
256 return true; 254 return true;
257 255
258 case if_expr: /* 'if' '(' <expr> ')' <stmt> */ 256 case if_expr: /* 'if' '(' <expr> ')' <stmt> */
259 ps.p_stack[--ps.tos] = if_expr_stmt; 257 ps.p_stack[--ps.tos] = if_expr_stmt;
260 int i = ps.tos - 1; 258 int i = ps.tos - 1;
261 while (ps.p_stack[i] != stmt && 259 while (ps.p_stack[i] != stmt &&
262 ps.p_stack[i] != stmt_list && 260 ps.p_stack[i] != stmt_list &&
263 ps.p_stack[i] != lbrace) 261 ps.p_stack[i] != lbrace)
264 --i; 262 --i;
265 ps.i_l_follow = ps.il[i]; 263 ps.i_l_follow = ps.il[i];
266 /* 264 /*
267 * for the time being, we will assume that there is no else on 265 * for the time being, we will assume that there is no else on
268 * this if, and set the indentation level accordingly. If an 266 * this if, and set the indentation level accordingly. If an
269 * else is scanned, it will be fixed up later 267 * else is scanned, it will be fixed up later
270 */ 268 */
271 return true; 269 return true;
272 270
273 case switch_expr: /* 'switch' '(' <expr> ')' <stmt> */ 271 case switch_expr: /* 'switch' '(' <expr> ')' <stmt> */
274 case_ind = ps.cstk[ps.tos - 1]; 272 case_ind = ps.cstk[ps.tos - 1];
275 /* FALLTHROUGH */ 273 /* FALLTHROUGH */
276 case decl: /* finish of a declaration */ 274 case decl: /* finish of a declaration */
277 case if_expr_stmt_else: /* 'if' '(' <expr> ')' <stmt> 'else' <stmt> */ 275 case if_expr_stmt_else: /* 'if' '(' <expr> ')' <stmt> 'else' <stmt> */
278 case for_exprs: /* 'for' '(' ... ')' <stmt> */ 276 case for_exprs: /* 'for' '(' ... ')' <stmt> */
279 case while_expr: /* 'while' '(' <expr> ')' <stmt> */ 277 case while_expr: /* 'while' '(' <expr> ')' <stmt> */
280 ps.p_stack[--ps.tos] = stmt; 278 ps.p_stack[--ps.tos] = stmt;
281 ps.i_l_follow = ps.il[ps.tos]; 279 ps.i_l_follow = ps.il[ps.tos];
282 return true; 280 return true;
283 281
284 default: /* <anything else> <stmt> */ 282 default: /* <anything else> <stmt> */
285 return false; 283 return false;
286 } 284 }
287} 285}
288 286
289/* 287/*
290 * Repeatedly try to reduce the top two symbols on the parse stack to a 288 * Repeatedly try to reduce the top two symbols on the parse stack to a
291 * single symbol, until no more reductions are possible. 289 * single symbol, until no more reductions are possible.
292 * 290 *
293 * On each reduction, ps.i_l_follow (the indentation for the following line) 291 * On each reduction, ps.i_l_follow (the indentation for the following line)
294 * is set to the indentation level associated with the old TOS. 292 * is set to the indentation level associated with the old TOS.
295 */ 293 */
296static void 294static void
297reduce(void) 295reduce(void)
298{ 296{
299again: 297again:
300 if (ps.p_stack[ps.tos] == stmt) { 298 if (ps.p_stack[ps.tos] == stmt) {
301 if (reduce_stmt()) 299 if (reduce_stmt())
302 goto again; 300 goto again;
303 } else if (ps.p_stack[ps.tos] == while_expr) { 301 } else if (ps.p_stack[ps.tos] == while_expr) {
304 if (ps.p_stack[ps.tos - 1] == do_stmt) { 302 if (ps.p_stack[ps.tos - 1] == do_stmt) {
305 ps.tos -= 2; 303 ps.tos -= 2;
306 goto again; 304 goto again;
307 } 305 }
308 } 306 }
309} 307}