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