| @@ -1,1585 +1,1589 @@ | | | @@ -1,1585 +1,1589 @@ |
1 | /* $NetBSD: indent.c,v 1.54 2021/03/13 12:52:24 rillig Exp $ */ | | 1 | /* $NetBSD: indent.c,v 1.55 2021/03/13 13:14:14 rillig Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * SPDX-License-Identifier: BSD-4-Clause | | 4 | * SPDX-License-Identifier: BSD-4-Clause |
5 | * | | 5 | * |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. |
7 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. | | 7 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. |
8 | * Copyright (c) 1980, 1993 | | 8 | * Copyright (c) 1980, 1993 |
9 | * The Regents of the University of California. All rights reserved. | | 9 | * The Regents of the University of California. All rights reserved. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. | | 15 | * notice, this list of conditions and the following disclaimer. |
16 | * 2. Redistributions in binary form must reproduce the above copyright | | 16 | * 2. Redistributions in binary form must reproduce the above copyright |
17 | * notice, this list of conditions and the following disclaimer in the | | 17 | * notice, this list of conditions and the following disclaimer in the |
18 | * documentation and/or other materials provided with the distribution. | | 18 | * documentation and/or other materials provided with the distribution. |
19 | * 3. All advertising materials mentioning features or use of this software | | 19 | * 3. All advertising materials mentioning features or use of this software |
20 | * must display the following acknowledgement: | | 20 | * must display the following acknowledgement: |
21 | * This product includes software developed by the University of | | 21 | * This product includes software developed by the University of |
22 | * California, Berkeley and its contributors. | | 22 | * California, Berkeley and its contributors. |
23 | * 4. Neither the name of the University nor the names of its contributors | | 23 | * 4. Neither the name of the University nor the names of its contributors |
24 | * may be used to endorse or promote products derived from this software | | 24 | * may be used to endorse or promote products derived from this software |
25 | * without specific prior written permission. | | 25 | * without specific prior written permission. |
26 | * | | 26 | * |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
37 | * SUCH DAMAGE. | | 37 | * SUCH DAMAGE. |
38 | */ | | 38 | */ |
39 | | | 39 | |
40 | #if 0 | | 40 | #if 0 |
41 | #ifndef lint | | 41 | #ifndef lint |
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.54 2021/03/13 12:52:24 rillig Exp $"); | | 49 | __RCSID("$NetBSD: indent.c,v 1.55 2021/03/13 13:14:14 rillig Exp $"); |
50 | #elif defined(__FreeBSD__) | | 50 | #elif defined(__FreeBSD__) |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); | | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); |
52 | #endif | | 52 | #endif |
53 | #endif | | 53 | #endif |
54 | | | 54 | |
55 | #include <sys/param.h> | | 55 | #include <sys/param.h> |
56 | #if HAVE_CAPSICUM | | 56 | #if HAVE_CAPSICUM |
57 | #include <sys/capsicum.h> | | 57 | #include <sys/capsicum.h> |
58 | #include <capsicum_helpers.h> | | 58 | #include <capsicum_helpers.h> |
59 | #endif | | 59 | #endif |
60 | #include <err.h> | | 60 | #include <err.h> |
61 | #include <errno.h> | | 61 | #include <errno.h> |
62 | #include <fcntl.h> | | 62 | #include <fcntl.h> |
63 | #include <unistd.h> | | 63 | #include <unistd.h> |
64 | #include <stdio.h> | | 64 | #include <stdio.h> |
65 | #include <stdlib.h> | | 65 | #include <stdlib.h> |
66 | #include <string.h> | | 66 | #include <string.h> |
67 | #include <ctype.h> | | 67 | #include <ctype.h> |
68 | | | 68 | |
69 | #include "indent.h" | | 69 | #include "indent.h" |
70 | | | 70 | |
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 | static void | | 369 | static void |
370 | main_init_globals(void) | | 370 | main_init_globals(void) |
371 | { | | 371 | { |
372 | found_err = 0; | | 372 | found_err = 0; |
373 | | | 373 | |
374 | ps.p_stack[0] = stmt; /* this is the parser's stack */ | | 374 | ps.p_stack[0] = stmt; /* this is the parser's stack */ |
375 | ps.last_nl = true; /* this is true if the last thing scanned was | | 375 | ps.last_nl = true; /* this is true if the last thing scanned was |
376 | * a newline */ | | 376 | * a newline */ |
377 | ps.last_token = semicolon; | | 377 | ps.last_token = semicolon; |
378 | combuf = malloc(bufsize); | | 378 | combuf = malloc(bufsize); |
379 | if (combuf == NULL) | | 379 | if (combuf == NULL) |
380 | err(1, NULL); | | 380 | err(1, NULL); |
381 | labbuf = malloc(bufsize); | | 381 | labbuf = malloc(bufsize); |
382 | if (labbuf == NULL) | | 382 | if (labbuf == NULL) |
383 | err(1, NULL); | | 383 | err(1, NULL); |
384 | codebuf = malloc(bufsize); | | 384 | codebuf = malloc(bufsize); |
385 | if (codebuf == NULL) | | 385 | if (codebuf == NULL) |
386 | err(1, NULL); | | 386 | err(1, NULL); |
387 | tokenbuf = malloc(bufsize); | | 387 | tokenbuf = malloc(bufsize); |
388 | if (tokenbuf == NULL) | | 388 | if (tokenbuf == NULL) |
389 | err(1, NULL); | | 389 | err(1, NULL); |
390 | alloc_typenames(); | | 390 | alloc_typenames(); |
391 | init_constant_tt(); | | 391 | init_constant_tt(); |
392 | l_com = combuf + bufsize - 5; | | 392 | l_com = combuf + bufsize - 5; |
393 | l_lab = labbuf + bufsize - 5; | | 393 | l_lab = labbuf + bufsize - 5; |
394 | l_code = codebuf + bufsize - 5; | | 394 | l_code = codebuf + bufsize - 5; |
395 | l_token = tokenbuf + bufsize - 5; | | 395 | l_token = tokenbuf + bufsize - 5; |
396 | combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and | | 396 | combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and |
397 | * comment buffers */ | | 397 | * comment buffers */ |
398 | combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; | | 398 | combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; |
399 | opt.else_if = 1; /* Default else-if special processing to on */ | | 399 | opt.else_if = 1; /* Default else-if special processing to on */ |
400 | s_lab = e_lab = labbuf + 1; | | 400 | s_lab = e_lab = labbuf + 1; |
401 | s_code = e_code = codebuf + 1; | | 401 | s_code = e_code = codebuf + 1; |
402 | s_com = e_com = combuf + 1; | | 402 | s_com = e_com = combuf + 1; |
403 | s_token = e_token = tokenbuf + 1; | | 403 | s_token = e_token = tokenbuf + 1; |
404 | | | 404 | |
405 | in_buffer = malloc(10); | | 405 | in_buffer = malloc(10); |
406 | if (in_buffer == NULL) | | 406 | if (in_buffer == NULL) |
407 | err(1, NULL); | | 407 | err(1, NULL); |
408 | in_buffer_limit = in_buffer + 8; | | 408 | in_buffer_limit = in_buffer + 8; |
409 | buf_ptr = buf_end = in_buffer; | | 409 | buf_ptr = buf_end = in_buffer; |
410 | line_no = 1; | | 410 | line_no = 1; |
411 | had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; | | 411 | had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; |
412 | ps.in_or_st = false; | | 412 | ps.in_or_st = false; |
413 | ps.bl_line = true; | | 413 | ps.bl_line = true; |
414 | ps.want_blank = ps.in_stmt = ps.ind_stmt = false; | | 414 | ps.want_blank = ps.in_stmt = ps.ind_stmt = false; |
415 | | | 415 | |
416 | ps.pcase = false; | | 416 | ps.pcase = false; |
417 | sc_end = NULL; | | 417 | sc_end = NULL; |
418 | bp_save = NULL; | | 418 | bp_save = NULL; |
419 | be_save = NULL; | | 419 | be_save = NULL; |
420 | | | 420 | |
421 | output = NULL; | | 421 | output = NULL; |
422 | | | 422 | |
423 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | | 423 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); |
424 | if (suffix != NULL) | | 424 | if (suffix != NULL) |
425 | simple_backup_suffix = suffix; | | 425 | simple_backup_suffix = suffix; |
426 | } | | 426 | } |
427 | | | 427 | |
428 | static void | | 428 | static void |
429 | main_parse_command_line(int argc, char **argv) | | 429 | main_parse_command_line(int argc, char **argv) |
430 | { | | 430 | { |
431 | int i; | | 431 | int i; |
432 | const char *profile_name = NULL; | | 432 | const char *profile_name = NULL; |
433 | | | 433 | |
434 | #if 0 | | 434 | #if 0 |
435 | max_line_length = 78; /* -l78 */ | | 435 | max_line_length = 78; /* -l78 */ |
436 | lineup_to_parens = 1; /* -lp */ | | 436 | lineup_to_parens = 1; /* -lp */ |
437 | lineup_to_parens_always = 0; /* -nlpl */ | | 437 | lineup_to_parens_always = 0; /* -nlpl */ |
438 | ps.ljust_decl = 0; /* -ndj */ | | 438 | ps.ljust_decl = 0; /* -ndj */ |
439 | ps.com_ind = 33; /* -c33 */ | | 439 | ps.com_ind = 33; /* -c33 */ |
440 | star_comment_cont = 1; /* -sc */ | | 440 | star_comment_cont = 1; /* -sc */ |
441 | ps.ind_size = 8; /* -i8 */ | | 441 | ps.ind_size = 8; /* -i8 */ |
442 | verbose = 0; | | 442 | verbose = 0; |
443 | ps.decl_indent = 16; /* -di16 */ | | 443 | ps.decl_indent = 16; /* -di16 */ |
444 | ps.local_decl_indent = -1; /* if this is not set to some nonnegative value | | 444 | ps.local_decl_indent = -1; /* if this is not set to some nonnegative value |
445 | * by an arg, we will set this equal to | | 445 | * by an arg, we will set this equal to |
446 | * ps.decl_ind */ | | 446 | * ps.decl_ind */ |
447 | ps.indent_parameters = 1; /* -ip */ | | 447 | ps.indent_parameters = 1; /* -ip */ |
448 | ps.decl_com_ind = 0; /* if this is not set to some positive value | | 448 | ps.decl_com_ind = 0; /* if this is not set to some positive value |
449 | * by an arg, we will set this equal to | | 449 | * by an arg, we will set this equal to |
450 | * ps.com_ind */ | | 450 | * ps.com_ind */ |
451 | btype_2 = 1; /* -br */ | | 451 | btype_2 = 1; /* -br */ |
452 | cuddle_else = 1; /* -ce */ | | 452 | cuddle_else = 1; /* -ce */ |
453 | ps.unindent_displace = 0; /* -d0 */ | | 453 | ps.unindent_displace = 0; /* -d0 */ |
454 | ps.case_indent = 0; /* -cli0 */ | | 454 | ps.case_indent = 0; /* -cli0 */ |
455 | format_block_comments = 1; /* -fcb */ | | 455 | format_block_comments = 1; /* -fcb */ |
456 | format_col1_comments = 1; /* -fc1 */ | | 456 | format_col1_comments = 1; /* -fc1 */ |
457 | procnames_start_line = 1; /* -psl */ | | 457 | procnames_start_line = 1; /* -psl */ |
458 | proc_calls_space = 0; /* -npcs */ | | 458 | proc_calls_space = 0; /* -npcs */ |
459 | comment_delimiter_on_blankline = 1; /* -cdb */ | | 459 | comment_delimiter_on_blankline = 1; /* -cdb */ |
460 | ps.leave_comma = 1; /* -nbc */ | | 460 | ps.leave_comma = 1; /* -nbc */ |
461 | #endif | | 461 | #endif |
462 | | | 462 | |
463 | for (i = 1; i < argc; ++i) | | 463 | for (i = 1; i < argc; ++i) |
464 | if (strcmp(argv[i], "-npro") == 0) | | 464 | if (strcmp(argv[i], "-npro") == 0) |
465 | break; | | 465 | break; |
466 | else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') | | 466 | else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') |
467 | profile_name = argv[i]; /* non-empty -P (set profile) */ | | 467 | profile_name = argv[i]; /* non-empty -P (set profile) */ |
468 | set_defaults(); | | 468 | set_defaults(); |
469 | if (i >= argc) | | 469 | if (i >= argc) |
470 | set_profile(profile_name); | | 470 | set_profile(profile_name); |
471 | | | 471 | |
472 | for (i = 1; i < argc; ++i) { | | 472 | for (i = 1; i < argc; ++i) { |
473 | | | 473 | |
474 | /* | | 474 | /* |
475 | * look thru args (if any) for changes to defaults | | 475 | * look thru args (if any) for changes to defaults |
476 | */ | | 476 | */ |
477 | if (argv[i][0] != '-') {/* no flag on parameter */ | | 477 | if (argv[i][0] != '-') {/* no flag on parameter */ |
478 | if (input == NULL) { /* we must have the input file */ | | 478 | if (input == NULL) { /* we must have the input file */ |
479 | in_name = argv[i]; /* remember name of input file */ | | 479 | in_name = argv[i]; /* remember name of input file */ |
480 | input = fopen(in_name, "r"); | | 480 | input = fopen(in_name, "r"); |
481 | if (input == NULL) /* check for open error */ | | 481 | if (input == NULL) /* check for open error */ |
482 | err(1, "%s", in_name); | | 482 | err(1, "%s", in_name); |
483 | continue; | | 483 | continue; |
484 | } else if (output == NULL) { /* we have the output file */ | | 484 | } else if (output == NULL) { /* we have the output file */ |
485 | out_name = argv[i]; /* remember name of output file */ | | 485 | out_name = argv[i]; /* remember name of output file */ |
486 | if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite | | 486 | if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite |
487 | * the file */ | | 487 | * the file */ |
488 | errx(1, "input and output files must be different"); | | 488 | errx(1, "input and output files must be different"); |
489 | } | | 489 | } |
490 | output = fopen(out_name, "w"); | | 490 | output = fopen(out_name, "w"); |
491 | if (output == NULL) /* check for create error */ | | 491 | if (output == NULL) /* check for create error */ |
492 | err(1, "%s", out_name); | | 492 | err(1, "%s", out_name); |
493 | continue; | | 493 | continue; |
494 | } | | 494 | } |
495 | errx(1, "unknown parameter: %s", argv[i]); | | 495 | errx(1, "unknown parameter: %s", argv[i]); |
496 | } else | | 496 | } else |
497 | set_option(argv[i]); | | 497 | set_option(argv[i]); |
498 | } /* end of for */ | | 498 | } /* end of for */ |
499 | if (input == NULL) | | 499 | if (input == NULL) |
500 | input = stdin; | | 500 | input = stdin; |
501 | if (output == NULL) { | | 501 | if (output == NULL) { |
502 | if (input == stdin) | | 502 | if (input == stdin) |
503 | output = stdout; | | 503 | output = stdout; |
504 | else { | | 504 | else { |
505 | out_name = in_name; | | 505 | out_name = in_name; |
506 | bakcopy(); | | 506 | bakcopy(); |
507 | } | | 507 | } |
508 | } | | 508 | } |
509 | | | 509 | |
510 | if (opt.com_ind <= 1) | | 510 | if (opt.com_ind <= 1) |
511 | opt.com_ind = 2; /* don't put normal comments before column 2 */ | | 511 | opt.com_ind = 2; /* don't put normal comments before column 2 */ |
512 | if (opt.block_comment_max_line_length <= 0) | | 512 | if (opt.block_comment_max_line_length <= 0) |
513 | opt.block_comment_max_line_length = opt.max_line_length; | | 513 | opt.block_comment_max_line_length = opt.max_line_length; |
514 | if (opt.local_decl_indent < 0) /* if not specified by user, set this */ | | 514 | if (opt.local_decl_indent < 0) /* if not specified by user, set this */ |
515 | opt.local_decl_indent = opt.decl_indent; | | 515 | opt.local_decl_indent = opt.decl_indent; |
516 | if (opt.decl_com_ind <= 0) /* if not specified by user, set this */ | | 516 | if (opt.decl_com_ind <= 0) /* if not specified by user, set this */ |
517 | opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind; | | 517 | opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind; |
518 | if (opt.continuation_indent == 0) | | 518 | if (opt.continuation_indent == 0) |
519 | opt.continuation_indent = opt.ind_size; | | 519 | opt.continuation_indent = opt.ind_size; |
520 | } | | 520 | } |
521 | | | 521 | |
522 | static void | | 522 | static void |
523 | main_prepare_parsing(void) | | 523 | main_prepare_parsing(void) |
524 | { | | 524 | { |
525 | fill_buffer(); /* get first batch of stuff into input buffer */ | | 525 | fill_buffer(); /* get first batch of stuff into input buffer */ |
526 | | | 526 | |
527 | parse(semicolon); | | 527 | parse(semicolon); |
528 | | | 528 | |
529 | char *p = buf_ptr; | | 529 | char *p = buf_ptr; |
530 | int col = 1; | | 530 | int col = 1; |
531 | | | 531 | |
532 | while (1) { | | 532 | while (1) { |
533 | if (*p == ' ') | | 533 | if (*p == ' ') |
534 | col++; | | 534 | col++; |
535 | else if (*p == '\t') | | 535 | else if (*p == '\t') |
536 | col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; | | 536 | col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; |
537 | else | | 537 | else |
538 | break; | | 538 | break; |
539 | p++; | | 539 | p++; |
540 | } | | 540 | } |
541 | if (col > opt.ind_size) | | 541 | if (col > opt.ind_size) |
542 | ps.ind_level = ps.i_l_follow = col / opt.ind_size; | | 542 | ps.ind_level = ps.i_l_follow = col / opt.ind_size; |
543 | } | | 543 | } |
544 | | | 544 | |
545 | static void | | 545 | static void |
546 | process_end_of_file(void) | | 546 | process_end_of_file(void) |
547 | { | | 547 | { |
548 | if (s_lab != e_lab || s_code != e_code || s_com != e_com) | | 548 | if (s_lab != e_lab || s_code != e_code || s_com != e_com) |
549 | dump_line(); | | 549 | dump_line(); |
550 | | | 550 | |
551 | if (ps.tos > 1) /* check for balanced braces */ | | 551 | if (ps.tos > 1) /* check for balanced braces */ |
552 | diag(1, "Stuff missing from end of file"); | | 552 | diag(1, "Stuff missing from end of file"); |
553 | | | 553 | |
554 | if (opt.verbose) { | | 554 | if (opt.verbose) { |
555 | printf("There were %d output lines and %d comments\n", | | 555 | printf("There were %d output lines and %d comments\n", |
556 | ps.out_lines, ps.out_coms); | | 556 | ps.out_lines, ps.out_coms); |
557 | printf("(Lines with comments)/(Lines with code): %6.3f\n", | | 557 | printf("(Lines with comments)/(Lines with code): %6.3f\n", |
558 | (1.0 * ps.com_lines) / code_lines); | | 558 | (1.0 * ps.com_lines) / code_lines); |
559 | } | | 559 | } |
560 | | | 560 | |
561 | fflush(output); | | 561 | fflush(output); |
562 | exit(found_err); | | 562 | exit(found_err); |
563 | } | | 563 | } |
564 | | | 564 | |
565 | static void | | 565 | static void |
566 | process_comment_in_code(token_type type_code, int *inout_force_nl) | | 566 | process_comment_in_code(token_type type_code, int *inout_force_nl) |
567 | { | | 567 | { |
568 | if (*inout_force_nl && | | 568 | if (*inout_force_nl && |
569 | type_code != semicolon && | | 569 | type_code != semicolon && |
570 | (type_code != lbrace || !opt.btype_2)) { | | 570 | (type_code != lbrace || !opt.btype_2)) { |
571 | | | 571 | |
572 | /* we should force a broken line here */ | | 572 | /* we should force a broken line here */ |
573 | if (opt.verbose) | | 573 | if (opt.verbose) |
574 | diag(0, "Line broken"); | | 574 | diag(0, "Line broken"); |
575 | dump_line(); | | 575 | dump_line(); |
576 | ps.want_blank = false; /* dont insert blank at line start */ | | 576 | ps.want_blank = false; /* dont insert blank at line start */ |
577 | *inout_force_nl = false; | | 577 | *inout_force_nl = false; |
578 | } | | 578 | } |
579 | | | 579 | |
580 | ps.in_stmt = true; /* turn on flag which causes an extra level of | | 580 | ps.in_stmt = true; /* turn on flag which causes an extra level of |
581 | * indentation. this is turned off by a ; or | | 581 | * indentation. this is turned off by a ; or |
582 | * '}' */ | | 582 | * '}' */ |
583 | if (s_com != e_com) { /* the turkey has embedded a comment | | 583 | if (s_com != e_com) { /* the turkey has embedded a comment |
584 | * in a line. fix it */ | | 584 | * in a line. fix it */ |
585 | int len = e_com - s_com; | | 585 | int len = e_com - s_com; |
586 | | | 586 | |
587 | check_size_code(len + 3); | | 587 | check_size_code(len + 3); |
588 | *e_code++ = ' '; | | 588 | *e_code++ = ' '; |
589 | memcpy(e_code, s_com, len); | | 589 | memcpy(e_code, s_com, len); |
590 | e_code += len; | | 590 | e_code += len; |
591 | *e_code++ = ' '; | | 591 | *e_code++ = ' '; |
592 | *e_code = '\0'; /* null terminate code sect */ | | 592 | *e_code = '\0'; /* null terminate code sect */ |
593 | ps.want_blank = false; | | 593 | ps.want_blank = false; |
594 | e_com = s_com; | | 594 | e_com = s_com; |
595 | } | | 595 | } |
596 | } | | 596 | } |
597 | | | 597 | |
598 | static void | | 598 | static void |
599 | process_form_feed(void) | | 599 | process_form_feed(void) |
600 | { | | 600 | { |
601 | ps.use_ff = true; /* a form feed is treated much like a newline */ | | 601 | ps.use_ff = true; /* a form feed is treated much like a newline */ |
602 | dump_line(); | | 602 | dump_line(); |
603 | ps.want_blank = false; | | 603 | ps.want_blank = false; |
604 | } | | 604 | } |
605 | | | 605 | |
606 | static void | | 606 | static void |
607 | process_newline(void) | | 607 | process_newline(void) |
608 | { | | 608 | { |
609 | if (ps.last_token != comma || ps.p_l_follow > 0 | | 609 | if (ps.last_token != comma || ps.p_l_follow > 0 |
610 | || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { | | 610 | || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { |
611 | dump_line(); | | 611 | dump_line(); |
612 | ps.want_blank = false; | | 612 | ps.want_blank = false; |
613 | } | | 613 | } |
614 | ++line_no; /* keep track of input line number */ | | 614 | ++line_no; /* keep track of input line number */ |
615 | } | | 615 | } |
616 | | | 616 | |
617 | static void | | 617 | static void |
618 | process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw) | | 618 | process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw) |
619 | { | | 619 | { |
620 | /* count parens to make Healy happy */ | | 620 | /* count parens to make Healy happy */ |
621 | if (++ps.p_l_follow == nitems(ps.paren_indents)) { | | 621 | if (++ps.p_l_follow == nitems(ps.paren_indents)) { |
622 | diag(0, "Reached internal limit of %zu unclosed parens", | | 622 | diag(0, "Reached internal limit of %zu unclosed parens", |
623 | nitems(ps.paren_indents)); | | 623 | nitems(ps.paren_indents)); |
624 | ps.p_l_follow--; | | 624 | ps.p_l_follow--; |
625 | } | | 625 | } |
626 | if (*token == '[') | | 626 | if (*token == '[') |
627 | /* not a function pointer declaration or a function call */; | | 627 | /* not a function pointer declaration or a function call */; |
628 | else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && | | 628 | else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && |
629 | ps.procname[0] == '\0' && ps.paren_level == 0) { | | 629 | ps.procname[0] == '\0' && ps.paren_level == 0) { |
630 | /* function pointer declarations */ | | 630 | /* function pointer declarations */ |
631 | indent_declaration(dec_ind, tabs_to_var); | | 631 | indent_declaration(dec_ind, tabs_to_var); |
632 | ps.dumped_decl_indent = true; | | 632 | ps.dumped_decl_indent = true; |
633 | } else if (ps.want_blank && | | 633 | } else if (ps.want_blank && |
634 | ((ps.last_token != ident && ps.last_token != funcname) || | | 634 | ((ps.last_token != ident && ps.last_token != funcname) || |
635 | opt.proc_calls_space || | | 635 | opt.proc_calls_space || |
636 | (ps.keyword == rw_sizeof ? opt.Bill_Shannon : | | 636 | (ps.keyword == rw_sizeof ? opt.Bill_Shannon : |
637 | ps.keyword != rw_0 && ps.keyword != rw_offsetof))) | | 637 | ps.keyword != rw_0 && ps.keyword != rw_offsetof))) |
638 | *e_code++ = ' '; | | 638 | *e_code++ = ' '; |
639 | ps.want_blank = false; | | 639 | ps.want_blank = false; |
640 | *e_code++ = token[0]; | | 640 | *e_code++ = token[0]; |
641 | ps.paren_indents[ps.p_l_follow - 1] = | | 641 | ps.paren_indents[ps.p_l_follow - 1] = |
642 | indentation_after_range(0, s_code, e_code); | | 642 | indentation_after_range(0, s_code, e_code); |
643 | if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent | | 643 | if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent |
644 | && ps.paren_indents[0] < 2 * opt.ind_size) | | 644 | && ps.paren_indents[0] < 2 * opt.ind_size) |
645 | ps.paren_indents[0] = 2 * opt.ind_size; | | 645 | ps.paren_indents[0] = 2 * opt.ind_size; |
646 | if (ps.in_or_st && *token == '(' && ps.tos <= 2) { | | 646 | if (ps.in_or_st && *token == '(' && ps.tos <= 2) { |
647 | /* | | 647 | /* |
648 | * this is a kluge to make sure that declarations will be | | 648 | * this is a kluge to make sure that declarations will be |
649 | * aligned right if proc decl has an explicit type on it, i.e. | | 649 | * aligned right if proc decl has an explicit type on it, i.e. |
650 | * "int a(x) {..." | | 650 | * "int a(x) {..." |
651 | */ | | 651 | */ |
652 | parse(semicolon); /* I said this was a kluge... */ | | 652 | parse(semicolon); /* I said this was a kluge... */ |
653 | ps.in_or_st = false; /* turn off flag for structure decl or | | 653 | ps.in_or_st = false; /* turn off flag for structure decl or |
654 | * initialization */ | | 654 | * initialization */ |
655 | } | | 655 | } |
656 | /* parenthesized type following sizeof or offsetof is not a cast */ | | 656 | /* parenthesized type following sizeof or offsetof is not a cast */ |
657 | if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) | | 657 | if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) |
658 | ps.not_cast_mask |= 1 << ps.p_l_follow; | | 658 | ps.not_cast_mask |= 1 << ps.p_l_follow; |
659 | } | | 659 | } |
660 | | | 660 | |
661 | static void | | 661 | static void |
662 | process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl, | | 662 | process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl, |
663 | token_type hd_type) | | 663 | token_type hd_type) |
664 | { | | 664 | { |
665 | if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { | | 665 | if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { |
666 | ps.last_u_d = true; | | 666 | ps.last_u_d = true; |
667 | ps.cast_mask &= (1 << ps.p_l_follow) - 1; | | 667 | ps.cast_mask &= (1 << ps.p_l_follow) - 1; |
668 | ps.want_blank = opt.space_after_cast; | | 668 | ps.want_blank = opt.space_after_cast; |
669 | } else | | 669 | } else |
670 | ps.want_blank = true; | | 670 | ps.want_blank = true; |
671 | ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; | | 671 | ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; |
672 | | | 672 | |
673 | if (--ps.p_l_follow < 0) { | | 673 | if (--ps.p_l_follow < 0) { |
674 | ps.p_l_follow = 0; | | 674 | ps.p_l_follow = 0; |
675 | diag(0, "Extra %c", *token); | | 675 | diag(0, "Extra %c", *token); |
676 | } | | 676 | } |
677 | | | 677 | |
678 | if (e_code == s_code) /* if the paren starts the line */ | | 678 | if (e_code == s_code) /* if the paren starts the line */ |
679 | ps.paren_level = ps.p_l_follow; /* then indent it */ | | 679 | ps.paren_level = ps.p_l_follow; /* then indent it */ |
680 | | | 680 | |
681 | *e_code++ = token[0]; | | 681 | *e_code++ = token[0]; |
682 | | | 682 | |
683 | if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if | | 683 | if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if |
684 | * (...), or some such */ | | 684 | * (...), or some such */ |
685 | *inout_sp_sw = false; | | 685 | *inout_sp_sw = false; |
686 | *inout_force_nl = true; /* must force newline after if */ | | 686 | *inout_force_nl = true; /* must force newline after if */ |
687 | ps.last_u_d = true; /* inform lexi that a following | | 687 | ps.last_u_d = true; /* inform lexi that a following |
688 | * operator is unary */ | | 688 | * operator is unary */ |
689 | ps.in_stmt = false; /* dont use stmt continuation indentation */ | | 689 | ps.in_stmt = false; /* dont use stmt continuation indentation */ |
690 | | | 690 | |
691 | parse(hd_type); /* let parser worry about if, or whatever */ | | 691 | parse(hd_type); /* let parser worry about if, or whatever */ |
692 | } | | 692 | } |
693 | ps.search_brace = opt.btype_2; /* this should ensure that constructs such | | 693 | ps.search_brace = opt.btype_2; /* this should ensure that constructs such |
694 | * as main(){...} and int[]{...} have their | | 694 | * as main(){...} and int[]{...} have their |
695 | * braces put in the right place */ | | 695 | * braces put in the right place */ |
696 | } | | 696 | } |
697 | | | 697 | |
698 | static void | | 698 | static void |
699 | process_unary_op(int dec_ind, int tabs_to_var) | | 699 | process_unary_op(int dec_ind, int tabs_to_var) |
700 | { | | 700 | { |
701 | if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && | | 701 | if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && |
702 | ps.procname[0] == '\0' && ps.paren_level == 0) { | | 702 | ps.procname[0] == '\0' && ps.paren_level == 0) { |
703 | /* pointer declarations */ | | 703 | /* pointer declarations */ |
704 | | | 704 | |
705 | /* | | 705 | /* |
706 | * if this is a unary op in a declaration, we should indent | | 706 | * if this is a unary op in a declaration, we should indent |
707 | * this token | | 707 | * this token |
708 | */ | | 708 | */ |
709 | int i; | | 709 | int i; |
710 | for (i = 0; token[i]; ++i) | | 710 | for (i = 0; token[i]; ++i) |
711 | /* find length of token */; | | 711 | /* find length of token */; |
712 | indent_declaration(dec_ind - i, tabs_to_var); | | 712 | indent_declaration(dec_ind - i, tabs_to_var); |
713 | ps.dumped_decl_indent = true; | | 713 | ps.dumped_decl_indent = true; |
714 | } else if (ps.want_blank) | | 714 | } else if (ps.want_blank) |
715 | *e_code++ = ' '; | | 715 | *e_code++ = ' '; |
716 | | | 716 | |
717 | { | | 717 | { |
718 | int len = e_token - s_token; | | 718 | int len = e_token - s_token; |
719 | | | 719 | |
720 | check_size_code(len); | | 720 | check_size_code(len); |
721 | memcpy(e_code, token, len); | | 721 | memcpy(e_code, token, len); |
722 | e_code += len; | | 722 | e_code += len; |
723 | } | | 723 | } |
724 | ps.want_blank = false; | | 724 | ps.want_blank = false; |
725 | } | | 725 | } |
726 | | | 726 | |
727 | static void | | 727 | static void |
728 | process_binary_op(void) | | 728 | process_binary_op(void) |
729 | { | | 729 | { |
730 | int len = e_token - s_token; | | 730 | int len = e_token - s_token; |
731 | | | 731 | |
732 | check_size_code(len + 1); | | 732 | check_size_code(len + 1); |
733 | if (ps.want_blank) | | 733 | if (ps.want_blank) |
734 | *e_code++ = ' '; | | 734 | *e_code++ = ' '; |
735 | memcpy(e_code, token, len); | | 735 | memcpy(e_code, token, len); |
736 | e_code += len; | | 736 | e_code += len; |
737 | | | 737 | |
738 | ps.want_blank = true; | | 738 | ps.want_blank = true; |
739 | } | | 739 | } |
740 | | | 740 | |
741 | static void | | 741 | static void |
742 | process_postfix_op(void) | | 742 | process_postfix_op(void) |
743 | { | | 743 | { |
744 | *e_code++ = token[0]; | | 744 | *e_code++ = token[0]; |
745 | *e_code++ = token[1]; | | 745 | *e_code++ = token[1]; |
746 | ps.want_blank = true; | | 746 | ps.want_blank = true; |
747 | } | | 747 | } |
748 | | | 748 | |
749 | static void | | 749 | static void |
750 | process_question(int *inout_squest) | | 750 | process_question(int *inout_squest) |
751 | { | | 751 | { |
752 | (*inout_squest)++; /* this will be used when a later colon | | 752 | (*inout_squest)++; /* this will be used when a later colon |
753 | * appears so we can distinguish the | | 753 | * appears so we can distinguish the |
754 | * <c>?<n>:<n> construct */ | | 754 | * <c>?<n>:<n> construct */ |
755 | if (ps.want_blank) | | 755 | if (ps.want_blank) |
756 | *e_code++ = ' '; | | 756 | *e_code++ = ' '; |
757 | *e_code++ = '?'; | | 757 | *e_code++ = '?'; |
758 | ps.want_blank = true; | | 758 | ps.want_blank = true; |
759 | } | | 759 | } |
760 | | | 760 | |
761 | static void | | 761 | static void |
762 | process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase) | | 762 | process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase) |
763 | { | | 763 | { |
764 | if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */ | | 764 | if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */ |
765 | --*inout_squest; | | 765 | --*inout_squest; |
766 | if (ps.want_blank) | | 766 | if (ps.want_blank) |
767 | *e_code++ = ' '; | | 767 | *e_code++ = ' '; |
768 | *e_code++ = ':'; | | 768 | *e_code++ = ':'; |
769 | ps.want_blank = true; | | 769 | ps.want_blank = true; |
770 | return; | | 770 | return; |
771 | } | | 771 | } |
772 | if (ps.in_or_st) { | | 772 | if (ps.in_or_st) { |
773 | *e_code++ = ':'; | | 773 | *e_code++ = ':'; |
774 | ps.want_blank = false; | | 774 | ps.want_blank = false; |
775 | return; | | 775 | return; |
776 | } | | 776 | } |
777 | ps.in_stmt = false; /* seeing a label does not imply we are in a | | 777 | ps.in_stmt = false; /* seeing a label does not imply we are in a |
778 | * stmt */ | | 778 | * stmt */ |
779 | /* | | 779 | /* |
780 | * turn everything so far into a label | | 780 | * turn everything so far into a label |
781 | */ | | 781 | */ |
782 | { | | 782 | { |
783 | int len = e_code - s_code; | | 783 | int len = e_code - s_code; |
784 | | | 784 | |
785 | check_size_label(len + 3); | | 785 | check_size_label(len + 3); |
786 | memcpy(e_lab, s_code, len); | | 786 | memcpy(e_lab, s_code, len); |
787 | e_lab += len; | | 787 | e_lab += len; |
788 | *e_lab++ = ':'; | | 788 | *e_lab++ = ':'; |
789 | *e_lab = '\0'; | | 789 | *e_lab = '\0'; |
790 | e_code = s_code; | | 790 | e_code = s_code; |
791 | } | | 791 | } |
792 | *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by | | 792 | *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by |
793 | * dump_line to decide how to | | 793 | * dump_line to decide how to |
794 | * indent the label. force_nl | | 794 | * indent the label. force_nl |
795 | * will force a case n: to be | | 795 | * will force a case n: to be |
796 | * on a line by itself */ | | 796 | * on a line by itself */ |
797 | *inout_scase = false; | | 797 | *inout_scase = false; |
798 | ps.want_blank = false; | | 798 | ps.want_blank = false; |
799 | } | | 799 | } |
800 | | | 800 | |
801 | static void | | 801 | static void |
802 | process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind, | | 802 | process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind, |
803 | int const tabs_to_var, int *inout_sp_sw, | | 803 | int const tabs_to_var, int *inout_sp_sw, |
804 | token_type const hd_type, | | 804 | token_type const hd_type, |
805 | int *inout_force_nl) | | 805 | int *inout_force_nl) |
806 | { | | 806 | { |
807 | if (ps.dec_nest == 0) | | 807 | if (ps.dec_nest == 0) |
808 | ps.in_or_st = false; /* we are not in an initialization or | | 808 | ps.in_or_st = false; /* we are not in an initialization or |
809 | * structure declaration */ | | 809 | * structure declaration */ |
810 | *inout_scase = false; /* these will only need resetting in an error */ | | 810 | *inout_scase = false; /* these will only need resetting in an error */ |
811 | *inout_squest = 0; | | 811 | *inout_squest = 0; |
812 | if (ps.last_token == rparen) | | 812 | if (ps.last_token == rparen) |
813 | ps.in_parameter_declaration = 0; | | 813 | ps.in_parameter_declaration = 0; |
814 | ps.cast_mask = 0; | | 814 | ps.cast_mask = 0; |
815 | ps.not_cast_mask = 0; | | 815 | ps.not_cast_mask = 0; |
816 | ps.block_init = 0; | | 816 | ps.block_init = 0; |
817 | ps.block_init_level = 0; | | 817 | ps.block_init_level = 0; |
818 | ps.just_saw_decl--; | | 818 | ps.just_saw_decl--; |
819 | | | 819 | |
820 | if (ps.in_decl && s_code == e_code && !ps.block_init && | | 820 | if (ps.in_decl && s_code == e_code && !ps.block_init && |
821 | !ps.dumped_decl_indent && ps.paren_level == 0) { | | 821 | !ps.dumped_decl_indent && ps.paren_level == 0) { |
822 | /* indent stray semicolons in declarations */ | | 822 | /* indent stray semicolons in declarations */ |
823 | indent_declaration(dec_ind - 1, tabs_to_var); | | 823 | indent_declaration(dec_ind - 1, tabs_to_var); |
824 | ps.dumped_decl_indent = true; | | 824 | ps.dumped_decl_indent = true; |
825 | } | | 825 | } |
826 | | | 826 | |
827 | ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level | | 827 | ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level |
828 | * structure declaration, we | | 828 | * structure declaration, we |
829 | * arent any more */ | | 829 | * arent any more */ |
830 | | | 830 | |
831 | if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { | | 831 | if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { |
832 | | | 832 | |
833 | /* | | 833 | /* |
834 | * This should be true iff there were unbalanced parens in the | | 834 | * This should be true iff there were unbalanced parens in the |
835 | * stmt. It is a bit complicated, because the semicolon might | | 835 | * stmt. It is a bit complicated, because the semicolon might |
836 | * be in a for stmt | | 836 | * be in a for stmt |
837 | */ | | 837 | */ |
838 | diag(1, "Unbalanced parens"); | | 838 | diag(1, "Unbalanced parens"); |
839 | ps.p_l_follow = 0; | | 839 | ps.p_l_follow = 0; |
840 | if (*inout_sp_sw) { /* this is a check for an if, while, etc. with | | 840 | if (*inout_sp_sw) { /* this is a check for an if, while, etc. with |
841 | * unbalanced parens */ | | 841 | * unbalanced parens */ |
842 | *inout_sp_sw = false; | | 842 | *inout_sp_sw = false; |
843 | parse(hd_type); /* dont lose the if, or whatever */ | | 843 | parse(hd_type); /* dont lose the if, or whatever */ |
844 | } | | 844 | } |
845 | } | | 845 | } |
846 | *e_code++ = ';'; | | 846 | *e_code++ = ';'; |
847 | ps.want_blank = true; | | 847 | ps.want_blank = true; |
848 | ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the | | 848 | ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the |
849 | * middle of a stmt */ | | 849 | * middle of a stmt */ |
850 | | | 850 | |
851 | if (!*inout_sp_sw) { /* if not if for (;;) */ | | 851 | if (!*inout_sp_sw) { /* if not if for (;;) */ |
852 | parse(semicolon); /* let parser know about end of stmt */ | | 852 | parse(semicolon); /* let parser know about end of stmt */ |
853 | *inout_force_nl = true;/* force newline after an end of stmt */ | | 853 | *inout_force_nl = true;/* force newline after an end of stmt */ |
854 | } | | 854 | } |
855 | } | | 855 | } |
856 | | | 856 | |
857 | static void | | 857 | static void |
858 | process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type, | | 858 | process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type, |
859 | int *di_stack, int di_stack_cap, int *inout_dec_ind) | | 859 | int *di_stack, int di_stack_cap, int *inout_dec_ind) |
860 | { | | 860 | { |
861 | ps.in_stmt = false; /* dont indent the {} */ | | 861 | ps.in_stmt = false; /* dont indent the {} */ |
862 | if (!ps.block_init) | | 862 | if (!ps.block_init) |
863 | *inout_force_nl = true; /* force other stuff on same line as '{' onto | | 863 | *inout_force_nl = true; /* force other stuff on same line as '{' onto |
864 | * new line */ | | 864 | * new line */ |
865 | else if (ps.block_init_level <= 0) | | 865 | else if (ps.block_init_level <= 0) |
866 | ps.block_init_level = 1; | | 866 | ps.block_init_level = 1; |
867 | else | | 867 | else |
868 | ps.block_init_level++; | | 868 | ps.block_init_level++; |
869 | | | 869 | |
870 | if (s_code != e_code && !ps.block_init) { | | 870 | if (s_code != e_code && !ps.block_init) { |
871 | if (!opt.btype_2) { | | 871 | if (!opt.btype_2) { |
872 | dump_line(); | | 872 | dump_line(); |
873 | ps.want_blank = false; | | 873 | ps.want_blank = false; |
874 | } else if (ps.in_parameter_declaration && !ps.in_or_st) { | | 874 | } else if (ps.in_parameter_declaration && !ps.in_or_st) { |
875 | ps.i_l_follow = 0; | | 875 | ps.i_l_follow = 0; |
876 | if (opt.function_brace_split) { /* dump the line prior | | 876 | if (opt.function_brace_split) { /* dump the line prior |
877 | * to the brace ... */ | | 877 | * to the brace ... */ |
878 | dump_line(); | | 878 | dump_line(); |
879 | ps.want_blank = false; | | 879 | ps.want_blank = false; |
880 | } else /* add a space between the decl and brace */ | | 880 | } else /* add a space between the decl and brace */ |
881 | ps.want_blank = true; | | 881 | ps.want_blank = true; |
882 | } | | 882 | } |
883 | } | | 883 | } |
884 | if (ps.in_parameter_declaration) | | 884 | if (ps.in_parameter_declaration) |
885 | prefix_blankline_requested = 0; | | 885 | prefix_blankline_requested = 0; |
886 | | | 886 | |
887 | if (ps.p_l_follow > 0) { /* check for preceding unbalanced | | 887 | if (ps.p_l_follow > 0) { /* check for preceding unbalanced |
888 | * parens */ | | 888 | * parens */ |
889 | diag(1, "Unbalanced parens"); | | 889 | diag(1, "Unbalanced parens"); |
890 | ps.p_l_follow = 0; | | 890 | ps.p_l_follow = 0; |
891 | if (*inout_sp_sw) { /* check for unclosed if, for, etc. */ | | 891 | if (*inout_sp_sw) { /* check for unclosed if, for, etc. */ |
892 | *inout_sp_sw = false; | | 892 | *inout_sp_sw = false; |
893 | parse(hd_type); | | 893 | parse(hd_type); |
894 | ps.ind_level = ps.i_l_follow; | | 894 | ps.ind_level = ps.i_l_follow; |
895 | } | | 895 | } |
896 | } | | 896 | } |
897 | if (s_code == e_code) | | 897 | if (s_code == e_code) |
898 | ps.ind_stmt = false; /* dont put extra indentation on line | | 898 | ps.ind_stmt = false; /* dont put extra indentation on line |
899 | * with '{' */ | | 899 | * with '{' */ |
900 | if (ps.in_decl && ps.in_or_st) { /* this is either a structure | | 900 | if (ps.in_decl && ps.in_or_st) { /* this is either a structure |
901 | * declaration or an init */ | | 901 | * declaration or an init */ |
902 | di_stack[ps.dec_nest] = *inout_dec_ind; | | 902 | di_stack[ps.dec_nest] = *inout_dec_ind; |
903 | if (++ps.dec_nest == di_stack_cap) { | | 903 | if (++ps.dec_nest == di_stack_cap) { |
904 | diag(0, "Reached internal limit of %d struct levels", | | 904 | diag(0, "Reached internal limit of %d struct levels", |
905 | di_stack_cap); | | 905 | di_stack_cap); |
906 | ps.dec_nest--; | | 906 | ps.dec_nest--; |
907 | } | | 907 | } |
908 | /* ? dec_ind = 0; */ | | 908 | /* ? dec_ind = 0; */ |
909 | } else { | | 909 | } else { |
910 | ps.decl_on_line = false; /* we can't be in the middle of | | 910 | ps.decl_on_line = false; /* we can't be in the middle of |
911 | * a declaration, so don't do | | 911 | * a declaration, so don't do |
912 | * special indentation of | | 912 | * special indentation of |
913 | * comments */ | | 913 | * comments */ |
914 | if (opt.blanklines_after_declarations_at_proctop | | 914 | if (opt.blanklines_after_declarations_at_proctop |
915 | && ps.in_parameter_declaration) | | 915 | && ps.in_parameter_declaration) |
916 | postfix_blankline_requested = 1; | | 916 | postfix_blankline_requested = 1; |
917 | ps.in_parameter_declaration = 0; | | 917 | ps.in_parameter_declaration = 0; |
918 | ps.in_decl = false; | | 918 | ps.in_decl = false; |
919 | } | | 919 | } |
920 | *inout_dec_ind = 0; | | 920 | *inout_dec_ind = 0; |
921 | parse(lbrace); /* let parser know about this */ | | 921 | parse(lbrace); /* let parser know about this */ |
922 | if (ps.want_blank) /* put a blank before '{' if '{' is not at | | 922 | if (ps.want_blank) /* put a blank before '{' if '{' is not at |
923 | * start of line */ | | 923 | * start of line */ |
924 | *e_code++ = ' '; | | 924 | *e_code++ = ' '; |
925 | ps.want_blank = false; | | 925 | ps.want_blank = false; |
926 | *e_code++ = '{'; | | 926 | *e_code++ = '{'; |
927 | ps.just_saw_decl = 0; | | 927 | ps.just_saw_decl = 0; |
928 | } | | 928 | } |
929 | | | 929 | |
930 | static void | | 930 | static void |
931 | process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack) | | 931 | process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack) |
932 | { | | 932 | { |
933 | if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be | | 933 | if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be |
934 | * omitted in declarations */ | | 934 | * omitted in declarations */ |
935 | parse(semicolon); | | 935 | parse(semicolon); |
936 | if (ps.p_l_follow) { /* check for unclosed if, for, else. */ | | 936 | if (ps.p_l_follow) { /* check for unclosed if, for, else. */ |
937 | diag(1, "Unbalanced parens"); | | 937 | diag(1, "Unbalanced parens"); |
938 | ps.p_l_follow = 0; | | 938 | ps.p_l_follow = 0; |
939 | *inout_sp_sw = false; | | 939 | *inout_sp_sw = false; |
940 | } | | 940 | } |
941 | ps.just_saw_decl = 0; | | 941 | ps.just_saw_decl = 0; |
942 | ps.block_init_level--; | | 942 | ps.block_init_level--; |
943 | if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */ | | 943 | if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */ |
944 | if (opt.verbose) | | 944 | if (opt.verbose) |
945 | diag(0, "Line broken"); | | 945 | diag(0, "Line broken"); |
946 | dump_line(); | | 946 | dump_line(); |
947 | } | | 947 | } |
948 | *e_code++ = '}'; | | 948 | *e_code++ = '}'; |
949 | ps.want_blank = true; | | 949 | ps.want_blank = true; |
950 | ps.in_stmt = ps.ind_stmt = false; | | 950 | ps.in_stmt = ps.ind_stmt = false; |
951 | if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */ | | 951 | if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */ |
952 | *inout_dec_ind = di_stack[--ps.dec_nest]; | | 952 | *inout_dec_ind = di_stack[--ps.dec_nest]; |
953 | if (ps.dec_nest == 0 && !ps.in_parameter_declaration) | | 953 | if (ps.dec_nest == 0 && !ps.in_parameter_declaration) |
954 | ps.just_saw_decl = 2; | | 954 | ps.just_saw_decl = 2; |
955 | ps.in_decl = true; | | 955 | ps.in_decl = true; |
956 | } | | 956 | } |
957 | prefix_blankline_requested = 0; | | 957 | prefix_blankline_requested = 0; |
958 | parse(rbrace); /* let parser know about this */ | | 958 | parse(rbrace); /* let parser know about this */ |
959 | ps.search_brace = opt.cuddle_else | | 959 | ps.search_brace = opt.cuddle_else |
960 | && ps.p_stack[ps.tos] == if_expr_stmt | | 960 | && ps.p_stack[ps.tos] == if_expr_stmt |
961 | && ps.il[ps.tos] >= ps.ind_level; | | 961 | && ps.il[ps.tos] >= ps.ind_level; |
962 | if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) | | 962 | if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) |
963 | postfix_blankline_requested = 1; | | 963 | postfix_blankline_requested = 1; |
964 | } | | 964 | } |
965 | | | 965 | |
966 | static void | | 966 | static void |
967 | process_keyword_do_else(int *inout_force_nl, int *inout_last_else) | | 967 | process_keyword_do_else(int *inout_force_nl, int *inout_last_else) |
968 | { | | 968 | { |
969 | ps.in_stmt = false; | | 969 | ps.in_stmt = false; |
970 | if (*token == 'e') { | | 970 | if (*token == 'e') { |
971 | if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { | | 971 | if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { |
972 | if (opt.verbose) | | 972 | if (opt.verbose) |
973 | diag(0, "Line broken"); | | 973 | diag(0, "Line broken"); |
974 | dump_line(); /* make sure this starts a line */ | | 974 | dump_line(); /* make sure this starts a line */ |
975 | ps.want_blank = false; | | 975 | ps.want_blank = false; |
976 | } | | 976 | } |
977 | *inout_force_nl = true;/* also, following stuff must go onto new line */ | | 977 | *inout_force_nl = true;/* also, following stuff must go onto new line */ |
978 | *inout_last_else = 1; | | 978 | *inout_last_else = 1; |
979 | parse(keyword_else); | | 979 | parse(keyword_else); |
980 | } else { | | 980 | } else { |
981 | if (e_code != s_code) { /* make sure this starts a line */ | | 981 | if (e_code != s_code) { /* make sure this starts a line */ |
982 | if (opt.verbose) | | 982 | if (opt.verbose) |
983 | diag(0, "Line broken"); | | 983 | diag(0, "Line broken"); |
984 | dump_line(); | | 984 | dump_line(); |
985 | ps.want_blank = false; | | 985 | ps.want_blank = false; |
986 | } | | 986 | } |
987 | *inout_force_nl = true;/* also, following stuff must go onto new line */ | | 987 | *inout_force_nl = true;/* also, following stuff must go onto new line */ |
988 | *inout_last_else = 0; | | 988 | *inout_last_else = 0; |
989 | parse(keyword_do); | | 989 | parse(keyword_do); |
990 | } | | 990 | } |
991 | } | | 991 | } |
992 | | | 992 | |
993 | static void | | 993 | static void |
994 | process_decl(int *out_dec_ind, int *out_tabs_to_var) | | 994 | process_decl(int *out_dec_ind, int *out_tabs_to_var) |
995 | { | | 995 | { |
996 | parse(decl); /* let parser worry about indentation */ | | 996 | parse(decl); /* let parser worry about indentation */ |
997 | if (ps.last_token == rparen && ps.tos <= 1) { | | 997 | if (ps.last_token == rparen && ps.tos <= 1) { |
998 | if (s_code != e_code) { | | 998 | if (s_code != e_code) { |
999 | dump_line(); | | 999 | dump_line(); |
1000 | ps.want_blank = 0; | | 1000 | ps.want_blank = 0; |
1001 | } | | 1001 | } |
1002 | } | | 1002 | } |
1003 | if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { | | 1003 | if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { |
1004 | ps.ind_level = ps.i_l_follow = 1; | | 1004 | ps.ind_level = ps.i_l_follow = 1; |
1005 | ps.ind_stmt = 0; | | 1005 | ps.ind_stmt = 0; |
1006 | } | | 1006 | } |
1007 | ps.in_or_st = true; /* this might be a structure or initialization | | 1007 | ps.in_or_st = true; /* this might be a structure or initialization |
1008 | * declaration */ | | 1008 | * declaration */ |
1009 | ps.in_decl = ps.decl_on_line = ps.last_token != type_def; | | 1009 | ps.in_decl = ps.decl_on_line = ps.last_token != type_def; |
1010 | if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) | | 1010 | if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) |
1011 | ps.just_saw_decl = 2; | | 1011 | ps.just_saw_decl = 2; |
1012 | prefix_blankline_requested = 0; | | 1012 | prefix_blankline_requested = 0; |
1013 | int i; | | 1013 | int i; |
1014 | for (i = 0; token[i++];); /* get length of token */ | | 1014 | for (i = 0; token[i++];); /* get length of token */ |
1015 | | | 1015 | |
1016 | if (ps.ind_level == 0 || ps.dec_nest > 0) { | | 1016 | if (ps.ind_level == 0 || ps.dec_nest > 0) { |
1017 | /* global variable or struct member in local variable */ | | 1017 | /* global variable or struct member in local variable */ |
1018 | *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; | | 1018 | *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; |
1019 | *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); | | 1019 | *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); |
1020 | } else { | | 1020 | } else { |
1021 | /* local variable */ | | 1021 | /* local variable */ |
1022 | *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; | | 1022 | *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; |
1023 | *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); | | 1023 | *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); |
1024 | } | | 1024 | } |
1025 | } | | 1025 | } |
1026 | | | 1026 | |
1027 | static void | | 1027 | static void |
1028 | process_ident(token_type type_code, int dec_ind, int tabs_to_var, | | 1028 | process_ident(token_type type_code, int dec_ind, int tabs_to_var, |
1029 | int *inout_sp_sw, int *inout_force_nl, token_type hd_type) | | 1029 | int *inout_sp_sw, int *inout_force_nl, token_type hd_type) |
1030 | { | | 1030 | { |
1031 | if (ps.in_decl) { | | 1031 | if (ps.in_decl) { |
1032 | if (type_code == funcname) { | | 1032 | if (type_code == funcname) { |
1033 | ps.in_decl = false; | | 1033 | ps.in_decl = false; |
1034 | if (opt.procnames_start_line && s_code != e_code) { | | 1034 | if (opt.procnames_start_line && s_code != e_code) { |
1035 | *e_code = '\0'; | | 1035 | *e_code = '\0'; |
1036 | dump_line(); | | 1036 | dump_line(); |
1037 | } else if (ps.want_blank) { | | 1037 | } else if (ps.want_blank) { |
1038 | *e_code++ = ' '; | | 1038 | *e_code++ = ' '; |
1039 | } | | 1039 | } |
1040 | ps.want_blank = false; | | 1040 | ps.want_blank = false; |
1041 | } else if (!ps.block_init && !ps.dumped_decl_indent && | | 1041 | } else if (!ps.block_init && !ps.dumped_decl_indent && |
1042 | ps.paren_level == 0) { /* if we are in a declaration, we | | 1042 | ps.paren_level == 0) { /* if we are in a declaration, we |
1043 | * must indent identifier */ | | 1043 | * must indent identifier */ |
1044 | indent_declaration(dec_ind, tabs_to_var); | | 1044 | indent_declaration(dec_ind, tabs_to_var); |
1045 | ps.dumped_decl_indent = true; | | 1045 | ps.dumped_decl_indent = true; |
1046 | ps.want_blank = false; | | 1046 | ps.want_blank = false; |
1047 | } | | 1047 | } |
1048 | } else if (*inout_sp_sw && ps.p_l_follow == 0) { | | 1048 | } else if (*inout_sp_sw && ps.p_l_follow == 0) { |
1049 | *inout_sp_sw = false; | | 1049 | *inout_sp_sw = false; |
1050 | *inout_force_nl = true; | | 1050 | *inout_force_nl = true; |
1051 | ps.last_u_d = true; | | 1051 | ps.last_u_d = true; |
1052 | ps.in_stmt = false; | | 1052 | ps.in_stmt = false; |
1053 | parse(hd_type); | | 1053 | parse(hd_type); |
1054 | } | | 1054 | } |
1055 | } | | 1055 | } |
1056 | | | 1056 | |
1057 | static void | | 1057 | static void |
1058 | copy_id(void) | | 1058 | copy_id(void) |
1059 | { | | 1059 | { |
1060 | int len = e_token - s_token; | | 1060 | int len = e_token - s_token; |
1061 | | | 1061 | |
1062 | check_size_code(len + 1); | | 1062 | check_size_code(len + 1); |
1063 | if (ps.want_blank) | | 1063 | if (ps.want_blank) |
1064 | *e_code++ = ' '; | | 1064 | *e_code++ = ' '; |
1065 | memcpy(e_code, s_token, len); | | 1065 | memcpy(e_code, s_token, len); |
1066 | e_code += len; | | 1066 | e_code += len; |
1067 | } | | 1067 | } |
1068 | | | 1068 | |
1069 | static void | | 1069 | static void |
1070 | process_string_prefix(void) | | 1070 | process_string_prefix(void) |
1071 | { | | 1071 | { |
1072 | int len = e_token - s_token; | | 1072 | int len = e_token - s_token; |
1073 | | | 1073 | |
1074 | check_size_code(len + 1); | | 1074 | check_size_code(len + 1); |
1075 | if (ps.want_blank) | | 1075 | if (ps.want_blank) |
1076 | *e_code++ = ' '; | | 1076 | *e_code++ = ' '; |
1077 | memcpy(e_code, token, len); | | 1077 | memcpy(e_code, token, len); |
1078 | e_code += len; | | 1078 | e_code += len; |
1079 | | | 1079 | |
1080 | ps.want_blank = false; | | 1080 | ps.want_blank = false; |
1081 | } | | 1081 | } |
1082 | | | 1082 | |
1083 | static void | | 1083 | static void |
1084 | process_period(void) | | 1084 | process_period(void) |
1085 | { | | 1085 | { |
1086 | *e_code++ = '.'; /* move the period into line */ | | 1086 | *e_code++ = '.'; /* move the period into line */ |
1087 | ps.want_blank = false; /* dont put a blank after a period */ | | 1087 | ps.want_blank = false; /* dont put a blank after a period */ |
1088 | } | | 1088 | } |
1089 | | | 1089 | |
1090 | static void | | 1090 | static void |
1091 | process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl) | | 1091 | process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl) |
1092 | { | | 1092 | { |
1093 | ps.want_blank = (s_code != e_code); /* only put blank after comma | | 1093 | ps.want_blank = (s_code != e_code); /* only put blank after comma |
1094 | * if comma does not start the line */ | | 1094 | * if comma does not start the line */ |
1095 | if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && | | 1095 | if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && |
1096 | !ps.dumped_decl_indent && ps.paren_level == 0) { | | 1096 | !ps.dumped_decl_indent && ps.paren_level == 0) { |
1097 | /* indent leading commas and not the actual identifiers */ | | 1097 | /* indent leading commas and not the actual identifiers */ |
1098 | indent_declaration(dec_ind - 1, tabs_to_var); | | 1098 | indent_declaration(dec_ind - 1, tabs_to_var); |
1099 | ps.dumped_decl_indent = true; | | 1099 | ps.dumped_decl_indent = true; |
1100 | } | | 1100 | } |
1101 | *e_code++ = ','; | | 1101 | *e_code++ = ','; |
1102 | if (ps.p_l_follow == 0) { | | 1102 | if (ps.p_l_follow == 0) { |
1103 | if (ps.block_init_level <= 0) | | 1103 | if (ps.block_init_level <= 0) |
1104 | ps.block_init = 0; | | 1104 | ps.block_init = 0; |
1105 | if (break_comma && (!opt.leave_comma || | | 1105 | if (break_comma && (!opt.leave_comma || |
1106 | indentation_after_range( | | 1106 | indentation_after_range( |
1107 | compute_code_indent(), s_code, e_code) | | 1107 | compute_code_indent(), s_code, e_code) |
1108 | >= opt.max_line_length - opt.tabsize)) | | 1108 | >= opt.max_line_length - opt.tabsize)) |
1109 | *inout_force_nl = true; | | 1109 | *inout_force_nl = true; |
1110 | } | | 1110 | } |
1111 | } | | 1111 | } |
1112 | | | 1112 | |
1113 | static void | | 1113 | static void |
1114 | process_preprocessing(void) | | 1114 | process_preprocessing(void) |
1115 | { | | 1115 | { |
1116 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | | 1116 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) |
1117 | dump_line(); | | 1117 | dump_line(); |
1118 | check_size_label(1); | | 1118 | check_size_label(1); |
1119 | *e_lab++ = '#'; /* move whole line to 'label' buffer */ | | 1119 | *e_lab++ = '#'; /* move whole line to 'label' buffer */ |
1120 | | | 1120 | |
1121 | { | | 1121 | { |
1122 | int in_comment = 0; | | 1122 | int in_comment = 0; |
1123 | int com_start = 0; | | 1123 | int com_start = 0; |
1124 | char quote = 0; | | 1124 | char quote = '\0'; |
1125 | int com_end = 0; | | 1125 | int com_end = 0; |
1126 | | | 1126 | |
1127 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | | 1127 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { |
1128 | buf_ptr++; | | 1128 | buf_ptr++; |
1129 | if (buf_ptr >= buf_end) | | 1129 | if (buf_ptr >= buf_end) |
1130 | fill_buffer(); | | 1130 | fill_buffer(); |
1131 | } | | 1131 | } |
1132 | while (*buf_ptr != '\n' || (in_comment && !had_eof)) { | | 1132 | while (*buf_ptr != '\n' || (in_comment && !had_eof)) { |
1133 | check_size_label(2); | | 1133 | check_size_label(2); |
1134 | *e_lab = *buf_ptr++; | | 1134 | *e_lab = *buf_ptr++; |
1135 | if (buf_ptr >= buf_end) | | 1135 | if (buf_ptr >= buf_end) |
1136 | fill_buffer(); | | 1136 | fill_buffer(); |
1137 | switch (*e_lab++) { | | 1137 | switch (*e_lab++) { |
1138 | case '\\': | | 1138 | case '\\': |
1139 | if (!in_comment) { | | 1139 | if (!in_comment) { |
1140 | *e_lab++ = *buf_ptr++; | | 1140 | *e_lab++ = *buf_ptr++; |
1141 | if (buf_ptr >= buf_end) | | 1141 | if (buf_ptr >= buf_end) |
1142 | fill_buffer(); | | 1142 | fill_buffer(); |
1143 | } | | 1143 | } |
1144 | break; | | 1144 | break; |
1145 | case '/': | | 1145 | case '/': |
1146 | if (*buf_ptr == '*' && !in_comment && !quote) { | | 1146 | if (*buf_ptr == '*' && !in_comment && quote == '\0') { |
1147 | in_comment = 1; | | 1147 | in_comment = 1; |
1148 | *e_lab++ = *buf_ptr++; | | 1148 | *e_lab++ = *buf_ptr++; |
1149 | com_start = e_lab - s_lab - 2; | | 1149 | com_start = e_lab - s_lab - 2; |
1150 | } | | 1150 | } |
1151 | break; | | 1151 | break; |
1152 | case '"': | | 1152 | case '"': |
1153 | if (quote == '"') | | 1153 | if (quote == '"') |
1154 | quote = 0; | | 1154 | quote = '\0'; |
| | | 1155 | else if (quote == '\0') |
| | | 1156 | quote = '"'; |
1155 | break; | | 1157 | break; |
1156 | case '\'': | | 1158 | case '\'': |
1157 | if (quote == '\'') | | 1159 | if (quote == '\'') |
1158 | quote = 0; | | 1160 | quote = '\0'; |
| | | 1161 | else if (quote == '\0') |
| | | 1162 | quote = '\''; |
1159 | break; | | 1163 | break; |
1160 | case '*': | | 1164 | case '*': |
1161 | if (*buf_ptr == '/' && in_comment) { | | 1165 | if (*buf_ptr == '/' && in_comment) { |
1162 | in_comment = 0; | | 1166 | in_comment = 0; |
1163 | *e_lab++ = *buf_ptr++; | | 1167 | *e_lab++ = *buf_ptr++; |
1164 | com_end = e_lab - s_lab; | | 1168 | com_end = e_lab - s_lab; |
1165 | } | | 1169 | } |
1166 | break; | | 1170 | break; |
1167 | } | | 1171 | } |
1168 | } | | 1172 | } |
1169 | | | 1173 | |
1170 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | | 1174 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) |
1171 | e_lab--; | | 1175 | e_lab--; |
1172 | if (e_lab - s_lab == com_end && bp_save == NULL) { | | 1176 | if (e_lab - s_lab == com_end && bp_save == NULL) { |
1173 | /* comment on preprocessor line */ | | 1177 | /* comment on preprocessor line */ |
1174 | if (sc_end == NULL) { /* if this is the first comment, | | 1178 | if (sc_end == NULL) { /* if this is the first comment, |
1175 | * we must set up the buffer */ | | 1179 | * we must set up the buffer */ |
1176 | save_com = sc_buf; | | 1180 | save_com = sc_buf; |
1177 | sc_end = &save_com[0]; | | 1181 | sc_end = &save_com[0]; |
1178 | } else { | | 1182 | } else { |
1179 | *sc_end++ = '\n'; /* add newline between | | 1183 | *sc_end++ = '\n'; /* add newline between |
1180 | * comments */ | | 1184 | * comments */ |
1181 | *sc_end++ = ' '; | | 1185 | *sc_end++ = ' '; |
1182 | --line_no; | | 1186 | --line_no; |
1183 | } | | 1187 | } |
1184 | if (sc_end - save_com + com_end - com_start > sc_size) | | 1188 | if (sc_end - save_com + com_end - com_start > sc_size) |
1185 | errx(1, "input too long"); | | 1189 | errx(1, "input too long"); |
1186 | memmove(sc_end, s_lab + com_start, com_end - com_start); | | 1190 | memmove(sc_end, s_lab + com_start, com_end - com_start); |
1187 | sc_end += com_end - com_start; | | 1191 | sc_end += com_end - com_start; |
1188 | e_lab = s_lab + com_start; | | 1192 | e_lab = s_lab + com_start; |
1189 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | | 1193 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) |
1190 | e_lab--; | | 1194 | e_lab--; |
1191 | bp_save = buf_ptr; /* save current input buffer */ | | 1195 | bp_save = buf_ptr; /* save current input buffer */ |
1192 | be_save = buf_end; | | 1196 | be_save = buf_end; |
1193 | buf_ptr = save_com; /* fix so that subsequent calls to | | 1197 | buf_ptr = save_com; /* fix so that subsequent calls to |
1194 | * lexi will take tokens out of | | 1198 | * lexi will take tokens out of |
1195 | * save_com */ | | 1199 | * save_com */ |
1196 | *sc_end++ = ' '; /* add trailing blank, just in case */ | | 1200 | *sc_end++ = ' '; /* add trailing blank, just in case */ |
1197 | buf_end = sc_end; | | 1201 | buf_end = sc_end; |
1198 | sc_end = NULL; | | 1202 | sc_end = NULL; |
1199 | } | | 1203 | } |
1200 | check_size_label(1); | | 1204 | check_size_label(1); |
1201 | *e_lab = '\0'; /* null terminate line */ | | 1205 | *e_lab = '\0'; /* null terminate line */ |
1202 | ps.pcase = false; | | 1206 | ps.pcase = false; |
1203 | } | | 1207 | } |
1204 | | | 1208 | |
1205 | if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ | | 1209 | if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ |
1206 | if ((size_t)ifdef_level < nitems(state_stack)) { | | 1210 | if ((size_t)ifdef_level < nitems(state_stack)) { |
1207 | match_state[ifdef_level].tos = -1; | | 1211 | match_state[ifdef_level].tos = -1; |
1208 | state_stack[ifdef_level++] = ps; | | 1212 | state_stack[ifdef_level++] = ps; |
1209 | } else | | 1213 | } else |
1210 | diag(1, "#if stack overflow"); | | 1214 | diag(1, "#if stack overflow"); |
1211 | } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ | | 1215 | } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ |
1212 | if (ifdef_level <= 0) | | 1216 | if (ifdef_level <= 0) |
1213 | diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); | | 1217 | diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); |
1214 | else { | | 1218 | else { |
1215 | match_state[ifdef_level - 1] = ps; | | 1219 | match_state[ifdef_level - 1] = ps; |
1216 | ps = state_stack[ifdef_level - 1]; | | 1220 | ps = state_stack[ifdef_level - 1]; |
1217 | } | | 1221 | } |
1218 | } else if (strncmp(s_lab, "#endif", 6) == 0) { | | 1222 | } else if (strncmp(s_lab, "#endif", 6) == 0) { |
1219 | if (ifdef_level <= 0) | | 1223 | if (ifdef_level <= 0) |
1220 | diag(1, "Unmatched #endif"); | | 1224 | diag(1, "Unmatched #endif"); |
1221 | else | | 1225 | else |
1222 | ifdef_level--; | | 1226 | ifdef_level--; |
1223 | } else { | | 1227 | } else { |
1224 | static const struct directives { | | 1228 | static const struct directives { |
1225 | int size; | | 1229 | int size; |
1226 | const char *string; | | 1230 | const char *string; |
1227 | } recognized[] = { | | 1231 | } recognized[] = { |
1228 | {7, "include"}, | | 1232 | {7, "include"}, |
1229 | {6, "define"}, | | 1233 | {6, "define"}, |
1230 | {5, "undef"}, | | 1234 | {5, "undef"}, |
1231 | {4, "line"}, | | 1235 | {4, "line"}, |
1232 | {5, "error"}, | | 1236 | {5, "error"}, |
1233 | {6, "pragma"} | | 1237 | {6, "pragma"} |
1234 | }; | | 1238 | }; |
1235 | int d = nitems(recognized); | | 1239 | int d = nitems(recognized); |
1236 | while (--d >= 0) | | 1240 | while (--d >= 0) |
1237 | if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) | | 1241 | if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) |
1238 | break; | | 1242 | break; |
1239 | if (d < 0) { | | 1243 | if (d < 0) { |
1240 | diag(1, "Unrecognized cpp directive"); | | 1244 | diag(1, "Unrecognized cpp directive"); |
1241 | return; | | 1245 | return; |
1242 | } | | 1246 | } |
1243 | } | | 1247 | } |
1244 | if (opt.blanklines_around_conditional_compilation) { | | 1248 | if (opt.blanklines_around_conditional_compilation) { |
1245 | postfix_blankline_requested++; | | 1249 | postfix_blankline_requested++; |
1246 | n_real_blanklines = 0; | | 1250 | n_real_blanklines = 0; |
1247 | } else { | | 1251 | } else { |
1248 | postfix_blankline_requested = 0; | | 1252 | postfix_blankline_requested = 0; |
1249 | prefix_blankline_requested = 0; | | 1253 | prefix_blankline_requested = 0; |
1250 | } | | 1254 | } |
1251 | | | 1255 | |
1252 | /* | | 1256 | /* |
1253 | * subsequent processing of the newline character will cause the line to | | 1257 | * subsequent processing of the newline character will cause the line to |
1254 | * be printed | | 1258 | * be printed |
1255 | */ | | 1259 | */ |
1256 | } | | 1260 | } |
1257 | | | 1261 | |
1258 | static void | | 1262 | static void |
1259 | main_loop(void) | | 1263 | main_loop(void) |
1260 | { | | 1264 | { |
1261 | token_type type_code; | | 1265 | token_type type_code; |
1262 | int force_nl; /* when true, code must be broken */ | | 1266 | int force_nl; /* when true, code must be broken */ |
1263 | int last_else = false; /* true iff last keyword was an else */ | | 1267 | int last_else = false; /* true iff last keyword was an else */ |
1264 | int dec_ind; /* current indentation for declarations */ | | 1268 | int dec_ind; /* current indentation for declarations */ |
1265 | int di_stack[20]; /* a stack of structure indentation levels */ | | 1269 | int di_stack[20]; /* a stack of structure indentation levels */ |
1266 | int tabs_to_var; /* true if using tabs to indent to var name */ | | 1270 | int tabs_to_var; /* true if using tabs to indent to var name */ |
1267 | int sp_sw; /* when true, we are in the expression of | | 1271 | int sp_sw; /* when true, we are in the expression of |
1268 | * if(...), while(...), etc. */ | | 1272 | * if(...), while(...), etc. */ |
1269 | token_type hd_type = end_of_file; /* used to store type of stmt | | 1273 | token_type hd_type = end_of_file; /* used to store type of stmt |
1270 | * for if (...), for (...), etc */ | | 1274 | * for if (...), for (...), etc */ |
1271 | int squest; /* when this is positive, we have seen a ? | | 1275 | int squest; /* when this is positive, we have seen a ? |
1272 | * without the matching : in a <c>?<s>:<s> | | 1276 | * without the matching : in a <c>?<s>:<s> |
1273 | * construct */ | | 1277 | * construct */ |
1274 | int scase; /* set to true when we see a case, so we will | | 1278 | int scase; /* set to true when we see a case, so we will |
1275 | * know what to do with the following colon */ | | 1279 | * know what to do with the following colon */ |
1276 | | | 1280 | |
1277 | sp_sw = force_nl = false; | | 1281 | sp_sw = force_nl = false; |
1278 | dec_ind = 0; | | 1282 | dec_ind = 0; |
1279 | di_stack[ps.dec_nest = 0] = 0; | | 1283 | di_stack[ps.dec_nest = 0] = 0; |
1280 | scase = false; | | 1284 | scase = false; |
1281 | squest = 0; | | 1285 | squest = 0; |
1282 | tabs_to_var = 0; | | 1286 | tabs_to_var = 0; |
1283 | | | 1287 | |
1284 | while (1) { /* this is the main loop. it will go until we | | 1288 | while (1) { /* this is the main loop. it will go until we |
1285 | * reach eof */ | | 1289 | * reach eof */ |
1286 | int comment_buffered = false; | | 1290 | int comment_buffered = false; |
1287 | | | 1291 | |
1288 | type_code = lexi(&ps); /* lexi reads one token. The actual | | 1292 | type_code = lexi(&ps); /* lexi reads one token. The actual |
1289 | * characters read are stored in "token". lexi | | 1293 | * characters read are stored in "token". lexi |
1290 | * returns a code indicating the type of token */ | | 1294 | * returns a code indicating the type of token */ |
1291 | | | 1295 | |
1292 | /* | | 1296 | /* |
1293 | * The following code moves newlines and comments following an if (), | | 1297 | * The following code moves newlines and comments following an if (), |
1294 | * while (), else, etc. up to the start of the following stmt to | | 1298 | * while (), else, etc. up to the start of the following stmt to |
1295 | * a buffer. This allows proper handling of both kinds of brace | | 1299 | * a buffer. This allows proper handling of both kinds of brace |
1296 | * placement (-br, -bl) and cuddling "else" (-ce). | | 1300 | * placement (-br, -bl) and cuddling "else" (-ce). |
1297 | */ | | 1301 | */ |
1298 | search_brace(&type_code, &force_nl, &comment_buffered, &last_else); | | 1302 | search_brace(&type_code, &force_nl, &comment_buffered, &last_else); |
1299 | | | 1303 | |
1300 | if (type_code == end_of_file) { | | 1304 | if (type_code == end_of_file) { |
1301 | process_end_of_file(); | | 1305 | process_end_of_file(); |
1302 | return; | | 1306 | return; |
1303 | } | | 1307 | } |
1304 | | | 1308 | |
1305 | if ( | | 1309 | if ( |
1306 | type_code != comment && | | 1310 | type_code != comment && |
1307 | type_code != newline && | | 1311 | type_code != newline && |
1308 | type_code != preprocessing && | | 1312 | type_code != preprocessing && |
1309 | type_code != form_feed) { | | 1313 | type_code != form_feed) { |
1310 | process_comment_in_code(type_code, &force_nl); | | 1314 | process_comment_in_code(type_code, &force_nl); |
1311 | | | 1315 | |
1312 | } else if (type_code != comment) /* preserve force_nl thru a comment */ | | 1316 | } else if (type_code != comment) /* preserve force_nl thru a comment */ |
1313 | force_nl = false; /* cancel forced newline after newline, form | | 1317 | force_nl = false; /* cancel forced newline after newline, form |
1314 | * feed, etc */ | | 1318 | * feed, etc */ |
1315 | | | 1319 | |
1316 | | | 1320 | |
1317 | | | 1321 | |
1318 | /*-----------------------------------------------------*\ | | 1322 | /*-----------------------------------------------------*\ |
1319 | | do switch on type of token scanned | | | 1323 | | do switch on type of token scanned | |
1320 | \*-----------------------------------------------------*/ | | 1324 | \*-----------------------------------------------------*/ |
1321 | check_size_code(3); /* maximum number of increments of e_code | | 1325 | check_size_code(3); /* maximum number of increments of e_code |
1322 | * before the next check_size_code or | | 1326 | * before the next check_size_code or |
1323 | * dump_line() is 2. After that there's the | | 1327 | * dump_line() is 2. After that there's the |
1324 | * final increment for the null character. */ | | 1328 | * final increment for the null character. */ |
1325 | switch (type_code) { /* now, decide what to do with the token */ | | 1329 | switch (type_code) { /* now, decide what to do with the token */ |
1326 | | | 1330 | |
1327 | case form_feed: /* found a form feed in line */ | | 1331 | case form_feed: /* found a form feed in line */ |
1328 | process_form_feed(); | | 1332 | process_form_feed(); |
1329 | break; | | 1333 | break; |
1330 | | | 1334 | |
1331 | case newline: | | 1335 | case newline: |
1332 | process_newline(); | | 1336 | process_newline(); |
1333 | break; | | 1337 | break; |
1334 | | | 1338 | |
1335 | case lparen: /* got a '(' or '[' */ | | 1339 | case lparen: /* got a '(' or '[' */ |
1336 | process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw); | | 1340 | process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw); |
1337 | break; | | 1341 | break; |
1338 | | | 1342 | |
1339 | case rparen: /* got a ')' or ']' */ | | 1343 | case rparen: /* got a ')' or ']' */ |
1340 | process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type); | | 1344 | process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type); |
1341 | break; | | 1345 | break; |
1342 | | | 1346 | |
1343 | case unary_op: /* this could be any unary operation */ | | 1347 | case unary_op: /* this could be any unary operation */ |
1344 | process_unary_op(dec_ind, tabs_to_var); | | 1348 | process_unary_op(dec_ind, tabs_to_var); |
1345 | break; | | 1349 | break; |
1346 | | | 1350 | |
1347 | case binary_op: /* any binary operation */ | | 1351 | case binary_op: /* any binary operation */ |
1348 | process_binary_op(); | | 1352 | process_binary_op(); |
1349 | break; | | 1353 | break; |
1350 | | | 1354 | |
1351 | case postfix_op: /* got a trailing ++ or -- */ | | 1355 | case postfix_op: /* got a trailing ++ or -- */ |
1352 | process_postfix_op(); | | 1356 | process_postfix_op(); |
1353 | break; | | 1357 | break; |
1354 | | | 1358 | |
1355 | case question: /* got a ? */ | | 1359 | case question: /* got a ? */ |
1356 | process_question(&squest); | | 1360 | process_question(&squest); |
1357 | break; | | 1361 | break; |
1358 | | | 1362 | |
1359 | case case_label: /* got word 'case' or 'default' */ | | 1363 | case case_label: /* got word 'case' or 'default' */ |
1360 | scase = true; /* so we can process the later colon properly */ | | 1364 | scase = true; /* so we can process the later colon properly */ |
1361 | goto copy_id; | | 1365 | goto copy_id; |
1362 | | | 1366 | |
1363 | case colon: /* got a ':' */ | | 1367 | case colon: /* got a ':' */ |
1364 | process_colon(&squest, &force_nl, &scase); | | 1368 | process_colon(&squest, &force_nl, &scase); |
1365 | break; | | 1369 | break; |
1366 | | | 1370 | |
1367 | case semicolon: /* got a ';' */ | | 1371 | case semicolon: /* got a ';' */ |
1368 | process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw, | | 1372 | process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw, |
1369 | hd_type, &force_nl); | | 1373 | hd_type, &force_nl); |
1370 | break; | | 1374 | break; |
1371 | | | 1375 | |
1372 | case lbrace: /* got a '{' */ | | 1376 | case lbrace: /* got a '{' */ |
1373 | process_lbrace(&force_nl, &sp_sw, hd_type, di_stack, | | 1377 | process_lbrace(&force_nl, &sp_sw, hd_type, di_stack, |
1374 | nitems(di_stack), &dec_ind); | | 1378 | nitems(di_stack), &dec_ind); |
1375 | break; | | 1379 | break; |
1376 | | | 1380 | |
1377 | case rbrace: /* got a '}' */ | | 1381 | case rbrace: /* got a '}' */ |
1378 | process_rbrace(&sp_sw, &dec_ind, di_stack); | | 1382 | process_rbrace(&sp_sw, &dec_ind, di_stack); |
1379 | break; | | 1383 | break; |
1380 | | | 1384 | |
1381 | case switch_expr: /* got keyword "switch" */ | | 1385 | case switch_expr: /* got keyword "switch" */ |
1382 | sp_sw = true; | | 1386 | sp_sw = true; |
1383 | hd_type = switch_expr; /* keep this for when we have seen the | | 1387 | hd_type = switch_expr; /* keep this for when we have seen the |
1384 | * expression */ | | 1388 | * expression */ |
1385 | goto copy_id; /* go move the token into buffer */ | | 1389 | goto copy_id; /* go move the token into buffer */ |
1386 | | | 1390 | |
1387 | case keyword_for_if_while: | | 1391 | case keyword_for_if_while: |
1388 | sp_sw = true; /* the interesting stuff is done after the | | 1392 | sp_sw = true; /* the interesting stuff is done after the |
1389 | * expression is scanned */ | | 1393 | * expression is scanned */ |
1390 | hd_type = (*token == 'i' ? if_expr : | | 1394 | hd_type = (*token == 'i' ? if_expr : |
1391 | (*token == 'w' ? while_expr : for_exprs)); | | 1395 | (*token == 'w' ? while_expr : for_exprs)); |
1392 | | | 1396 | |
1393 | /* remember the type of header for later use by parser */ | | 1397 | /* remember the type of header for later use by parser */ |
1394 | goto copy_id; /* copy the token into line */ | | 1398 | goto copy_id; /* copy the token into line */ |
1395 | | | 1399 | |
1396 | case keyword_do_else: | | 1400 | case keyword_do_else: |
1397 | process_keyword_do_else(&force_nl, &last_else); | | 1401 | process_keyword_do_else(&force_nl, &last_else); |
1398 | goto copy_id; /* move the token into line */ | | 1402 | goto copy_id; /* move the token into line */ |
1399 | | | 1403 | |
1400 | case type_def: | | 1404 | case type_def: |
1401 | case storage_class: | | 1405 | case storage_class: |
1402 | prefix_blankline_requested = 0; | | 1406 | prefix_blankline_requested = 0; |
1403 | goto copy_id; | | 1407 | goto copy_id; |
1404 | | | 1408 | |
1405 | case keyword_struct_union_enum: | | 1409 | case keyword_struct_union_enum: |
1406 | if (ps.p_l_follow > 0) | | 1410 | if (ps.p_l_follow > 0) |
1407 | goto copy_id; | | 1411 | goto copy_id; |
1408 | /* FALLTHROUGH */ | | 1412 | /* FALLTHROUGH */ |
1409 | case decl: /* we have a declaration type (int, etc.) */ | | 1413 | case decl: /* we have a declaration type (int, etc.) */ |
1410 | process_decl(&dec_ind, &tabs_to_var); | | 1414 | process_decl(&dec_ind, &tabs_to_var); |
1411 | goto copy_id; | | 1415 | goto copy_id; |
1412 | | | 1416 | |
1413 | case funcname: | | 1417 | case funcname: |
1414 | case ident: /* got an identifier or constant */ | | 1418 | case ident: /* got an identifier or constant */ |
1415 | process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl, | | 1419 | process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl, |
1416 | hd_type); | | 1420 | hd_type); |
1417 | copy_id: | | 1421 | copy_id: |
1418 | copy_id(); | | 1422 | copy_id(); |
1419 | if (type_code != funcname) | | 1423 | if (type_code != funcname) |
1420 | ps.want_blank = true; | | 1424 | ps.want_blank = true; |
1421 | break; | | 1425 | break; |
1422 | | | 1426 | |
1423 | case string_prefix: | | 1427 | case string_prefix: |
1424 | process_string_prefix(); | | 1428 | process_string_prefix(); |
1425 | break; | | 1429 | break; |
1426 | | | 1430 | |
1427 | case period: | | 1431 | case period: |
1428 | process_period(); | | 1432 | process_period(); |
1429 | break; | | 1433 | break; |
1430 | | | 1434 | |
1431 | case comma: | | 1435 | case comma: |
1432 | process_comma(dec_ind, tabs_to_var, &force_nl); | | 1436 | process_comma(dec_ind, tabs_to_var, &force_nl); |
1433 | break; | | 1437 | break; |
1434 | | | 1438 | |
1435 | case preprocessing: /* '#' */ | | 1439 | case preprocessing: /* '#' */ |
1436 | process_preprocessing(); | | 1440 | process_preprocessing(); |
1437 | break; | | 1441 | break; |
1438 | case comment: /* we have gotten a '/' followed by '*' */ | | 1442 | case comment: /* we have gotten a '/' followed by '*' */ |
1439 | pr_comment(); | | 1443 | pr_comment(); |
1440 | break; | | 1444 | break; |
1441 | | | 1445 | |
1442 | default: | | 1446 | default: |
1443 | break; | | 1447 | break; |
1444 | } /* end of big switch stmt */ | | 1448 | } /* end of big switch stmt */ |
1445 | | | 1449 | |
1446 | *e_code = '\0'; /* make sure code section is null terminated */ | | 1450 | *e_code = '\0'; /* make sure code section is null terminated */ |
1447 | if (type_code != comment && | | 1451 | if (type_code != comment && |
1448 | type_code != newline && | | 1452 | type_code != newline && |
1449 | type_code != preprocessing) | | 1453 | type_code != preprocessing) |
1450 | ps.last_token = type_code; | | 1454 | ps.last_token = type_code; |
1451 | } | | 1455 | } |
1452 | } | | 1456 | } |
1453 | | | 1457 | |
1454 | int | | 1458 | int |
1455 | main(int argc, char **argv) | | 1459 | main(int argc, char **argv) |
1456 | { | | 1460 | { |
1457 | main_init_globals(); | | 1461 | main_init_globals(); |
1458 | main_parse_command_line(argc, argv); | | 1462 | main_parse_command_line(argc, argv); |
1459 | #if HAVE_CAPSICUM | | 1463 | #if HAVE_CAPSICUM |
1460 | init_capsicum(); | | 1464 | init_capsicum(); |
1461 | #endif | | 1465 | #endif |
1462 | main_prepare_parsing(); | | 1466 | main_prepare_parsing(); |
1463 | main_loop(); | | 1467 | main_loop(); |
1464 | } | | 1468 | } |
1465 | | | 1469 | |
1466 | /* | | 1470 | /* |
1467 | * copy input file to backup file if in_name is /blah/blah/blah/file, then | | 1471 | * copy input file to backup file if in_name is /blah/blah/blah/file, then |
1468 | * backup file will be ".Bfile" then make the backup file the input and | | 1472 | * backup file will be ".Bfile" then make the backup file the input and |
1469 | * original input file the output | | 1473 | * original input file the output |
1470 | */ | | 1474 | */ |
1471 | static void | | 1475 | static void |
1472 | bakcopy(void) | | 1476 | bakcopy(void) |
1473 | { | | 1477 | { |
1474 | int n, | | 1478 | int n, |
1475 | bakchn; | | 1479 | bakchn; |
1476 | char buff[8 * 1024]; | | 1480 | char buff[8 * 1024]; |
1477 | const char *p; | | 1481 | const char *p; |
1478 | | | 1482 | |
1479 | /* construct file name .Bfile */ | | 1483 | /* construct file name .Bfile */ |
1480 | for (p = in_name; *p; p++); /* skip to end of string */ | | 1484 | for (p = in_name; *p; p++); /* skip to end of string */ |
1481 | while (p > in_name && *p != '/') /* find last '/' */ | | 1485 | while (p > in_name && *p != '/') /* find last '/' */ |
1482 | p--; | | 1486 | p--; |
1483 | if (*p == '/') | | 1487 | if (*p == '/') |
1484 | p++; | | 1488 | p++; |
1485 | sprintf(bakfile, "%s%s", p, simple_backup_suffix); | | 1489 | sprintf(bakfile, "%s%s", p, simple_backup_suffix); |
1486 | | | 1490 | |
1487 | /* copy in_name to backup file */ | | 1491 | /* copy in_name to backup file */ |
1488 | bakchn = creat(bakfile, 0600); | | 1492 | bakchn = creat(bakfile, 0600); |
1489 | if (bakchn < 0) | | 1493 | if (bakchn < 0) |
1490 | err(1, "%s", bakfile); | | 1494 | err(1, "%s", bakfile); |
1491 | while ((n = read(fileno(input), buff, sizeof(buff))) > 0) | | 1495 | while ((n = read(fileno(input), buff, sizeof(buff))) > 0) |
1492 | if (write(bakchn, buff, n) != n) | | 1496 | if (write(bakchn, buff, n) != n) |
1493 | err(1, "%s", bakfile); | | 1497 | err(1, "%s", bakfile); |
1494 | if (n < 0) | | 1498 | if (n < 0) |
1495 | err(1, "%s", in_name); | | 1499 | err(1, "%s", in_name); |
1496 | close(bakchn); | | 1500 | close(bakchn); |
1497 | fclose(input); | | 1501 | fclose(input); |
1498 | | | 1502 | |
1499 | /* re-open backup file as the input file */ | | 1503 | /* re-open backup file as the input file */ |
1500 | input = fopen(bakfile, "r"); | | 1504 | input = fopen(bakfile, "r"); |
1501 | if (input == NULL) | | 1505 | if (input == NULL) |
1502 | err(1, "%s", bakfile); | | 1506 | err(1, "%s", bakfile); |
1503 | /* now the original input file will be the output */ | | 1507 | /* now the original input file will be the output */ |
1504 | output = fopen(in_name, "w"); | | 1508 | output = fopen(in_name, "w"); |
1505 | if (output == NULL) { | | 1509 | if (output == NULL) { |
1506 | unlink(bakfile); | | 1510 | unlink(bakfile); |
1507 | err(1, "%s", in_name); | | 1511 | err(1, "%s", in_name); |
1508 | } | | 1512 | } |
1509 | } | | 1513 | } |
1510 | | | 1514 | |
1511 | static void | | 1515 | static void |
1512 | indent_declaration(int cur_dec_ind, int tabs_to_var) | | 1516 | indent_declaration(int cur_dec_ind, int tabs_to_var) |
1513 | { | | 1517 | { |
1514 | int pos = e_code - s_code; | | 1518 | int pos = e_code - s_code; |
1515 | char *startpos = e_code; | | 1519 | char *startpos = e_code; |
1516 | | | 1520 | |
1517 | /* | | 1521 | /* |
1518 | * get the tab math right for indentations that are not multiples of tabsize | | 1522 | * get the tab math right for indentations that are not multiples of tabsize |
1519 | */ | | 1523 | */ |
1520 | if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) { | | 1524 | if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) { |
1521 | pos += (ps.ind_level * opt.ind_size) % opt.tabsize; | | 1525 | pos += (ps.ind_level * opt.ind_size) % opt.tabsize; |
1522 | cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize; | | 1526 | cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize; |
1523 | } | | 1527 | } |
1524 | if (tabs_to_var) { | | 1528 | if (tabs_to_var) { |
1525 | int tpos; | | 1529 | int tpos; |
1526 | | | 1530 | |
1527 | check_size_code(cur_dec_ind / opt.tabsize); | | 1531 | check_size_code(cur_dec_ind / opt.tabsize); |
1528 | while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { | | 1532 | while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { |
1529 | *e_code++ = '\t'; | | 1533 | *e_code++ = '\t'; |
1530 | pos = tpos; | | 1534 | pos = tpos; |
1531 | } | | 1535 | } |
1532 | } | | 1536 | } |
1533 | check_size_code(cur_dec_ind - pos + 1); | | 1537 | check_size_code(cur_dec_ind - pos + 1); |
1534 | while (pos < cur_dec_ind) { | | 1538 | while (pos < cur_dec_ind) { |
1535 | *e_code++ = ' '; | | 1539 | *e_code++ = ' '; |
1536 | pos++; | | 1540 | pos++; |
1537 | } | | 1541 | } |
1538 | if (e_code == startpos && ps.want_blank) { | | 1542 | if (e_code == startpos && ps.want_blank) { |
1539 | *e_code++ = ' '; | | 1543 | *e_code++ = ' '; |
1540 | ps.want_blank = false; | | 1544 | ps.want_blank = false; |
1541 | } | | 1545 | } |
1542 | } | | 1546 | } |
1543 | | | 1547 | |
1544 | #ifdef debug | | 1548 | #ifdef debug |
1545 | void | | 1549 | void |
1546 | debug_printf(const char *fmt, ...) | | 1550 | debug_printf(const char *fmt, ...) |
1547 | { | | 1551 | { |
1548 | FILE *f = output == stdout ? stderr : stdout; | | 1552 | FILE *f = output == stdout ? stderr : stdout; |
1549 | va_list ap; | | 1553 | va_list ap; |
1550 | | | 1554 | |
1551 | va_start(ap, fmt); | | 1555 | va_start(ap, fmt); |
1552 | vfprintf(f, fmt, ap); | | 1556 | vfprintf(f, fmt, ap); |
1553 | va_end(ap); | | 1557 | va_end(ap); |
1554 | } | | 1558 | } |
1555 | | | 1559 | |
1556 | void | | 1560 | void |
1557 | debug_println(const char *fmt, ...) | | 1561 | debug_println(const char *fmt, ...) |
1558 | { | | 1562 | { |
1559 | FILE *f = output == stdout ? stderr : stdout; | | 1563 | FILE *f = output == stdout ? stderr : stdout; |
1560 | va_list ap; | | 1564 | va_list ap; |
1561 | | | 1565 | |
1562 | va_start(ap, fmt); | | 1566 | va_start(ap, fmt); |
1563 | vfprintf(f, fmt, ap); | | 1567 | vfprintf(f, fmt, ap); |
1564 | va_end(ap); | | 1568 | va_end(ap); |
1565 | fprintf(f, "\n"); | | 1569 | fprintf(f, "\n"); |
1566 | } | | 1570 | } |
1567 | | | 1571 | |
1568 | void | | 1572 | void |
1569 | debug_vis_range(const char *prefix, const char *s, const char *e, | | 1573 | debug_vis_range(const char *prefix, const char *s, const char *e, |
1570 | const char *suffix) | | 1574 | const char *suffix) |
1571 | { | | 1575 | { |
1572 | debug_printf("%s", prefix); | | 1576 | debug_printf("%s", prefix); |
1573 | for (const char *p = s; p < e; p++) { | | 1577 | for (const char *p = s; p < e; p++) { |
1574 | if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') | | 1578 | if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') |
1575 | debug_printf("%c", *p); | | 1579 | debug_printf("%c", *p); |
1576 | else if (*p == '\n') | | 1580 | else if (*p == '\n') |
1577 | debug_printf("\\n"); | | 1581 | debug_printf("\\n"); |
1578 | else if (*p == '\t') | | 1582 | else if (*p == '\t') |
1579 | debug_printf("\\t"); | | 1583 | debug_printf("\\t"); |
1580 | else | | 1584 | else |
1581 | debug_printf("\\x%02x", *p); | | 1585 | debug_printf("\\x%02x", *p); |
1582 | } | | 1586 | } |
1583 | debug_printf("%s", suffix); | | 1587 | debug_printf("%s", suffix); |
1584 | } | | 1588 | } |
1585 | #endif | | 1589 | #endif |