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