| @@ -1,1124 +1,1133 @@ | | | @@ -1,1124 +1,1133 @@ |
1 | /* $NetBSD: indent.c,v 1.375 2023/06/16 12:55:57 rillig Exp $ */ | | 1 | /* $NetBSD: indent.c,v 1.376 2023/06/16 14:12:10 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 | #include <sys/cdefs.h> | | 40 | #include <sys/cdefs.h> |
41 | __RCSID("$NetBSD: indent.c,v 1.375 2023/06/16 12:55:57 rillig Exp $"); | | 41 | __RCSID("$NetBSD: indent.c,v 1.376 2023/06/16 14:12:10 rillig Exp $"); |
42 | | | 42 | |
43 | #include <sys/param.h> | | 43 | #include <sys/param.h> |
44 | #include <err.h> | | 44 | #include <err.h> |
45 | #include <stdarg.h> | | 45 | #include <stdarg.h> |
46 | #include <stdio.h> | | 46 | #include <stdio.h> |
47 | #include <stdlib.h> | | 47 | #include <stdlib.h> |
48 | #include <string.h> | | 48 | #include <string.h> |
49 | | | 49 | |
50 | #include "indent.h" | | 50 | #include "indent.h" |
51 | | | 51 | |
52 | struct options opt = { | | 52 | struct options opt = { |
53 | .brace_same_line = true, | | 53 | .brace_same_line = true, |
54 | .comment_delimiter_on_blank_line = true, | | 54 | .comment_delimiter_on_blank_line = true, |
55 | .cuddle_else = true, | | 55 | .cuddle_else = true, |
56 | .comment_column = 33, | | 56 | .comment_column = 33, |
57 | .decl_indent = 16, | | 57 | .decl_indent = 16, |
58 | .else_if_in_same_line = true, | | 58 | .else_if_in_same_line = true, |
59 | .function_brace_split = true, | | 59 | .function_brace_split = true, |
60 | .format_col1_comments = true, | | 60 | .format_col1_comments = true, |
61 | .format_block_comments = true, | | 61 | .format_block_comments = true, |
62 | .indent_parameters = true, | | 62 | .indent_parameters = true, |
63 | .indent_size = 8, | | 63 | .indent_size = 8, |
64 | .local_decl_indent = -1, | | 64 | .local_decl_indent = -1, |
65 | .lineup_to_parens = true, | | 65 | .lineup_to_parens = true, |
66 | .procnames_start_line = true, | | 66 | .procnames_start_line = true, |
67 | .star_comment_cont = true, | | 67 | .star_comment_cont = true, |
68 | .tabsize = 8, | | 68 | .tabsize = 8, |
69 | .max_line_length = 78, | | 69 | .max_line_length = 78, |
70 | .use_tabs = true, | | 70 | .use_tabs = true, |
71 | }; | | 71 | }; |
72 | | | 72 | |
73 | struct parser_state ps; | | 73 | struct parser_state ps; |
74 | | | 74 | |
75 | struct buffer token; | | 75 | struct buffer token; |
76 | | | 76 | |
77 | struct buffer lab; | | 77 | struct buffer lab; |
78 | struct buffer code; | | 78 | struct buffer code; |
79 | struct buffer com; | | 79 | struct buffer com; |
80 | | | 80 | |
81 | bool found_err; | | 81 | bool found_err; |
82 | bool had_eof; | | 82 | bool had_eof; |
83 | int line_no = 1; | | 83 | int line_no = 1; |
84 | | | 84 | |
85 | static struct { | | 85 | static struct { |
86 | struct parser_state *item; | | 86 | struct parser_state *item; |
87 | size_t len; | | 87 | size_t len; |
88 | size_t cap; | | 88 | size_t cap; |
89 | } ifdef; | | 89 | } ifdef; |
90 | | | 90 | |
91 | FILE *input; | | 91 | FILE *input; |
92 | FILE *output; | | 92 | FILE *output; |
93 | | | 93 | |
94 | static const char *in_name = "Standard Input"; | | 94 | static const char *in_name = "Standard Input"; |
95 | static char backup_name[PATH_MAX]; | | 95 | static char backup_name[PATH_MAX]; |
96 | static const char *backup_suffix = ".BAK"; | | 96 | static const char *backup_suffix = ".BAK"; |
97 | | | 97 | |
98 | | | 98 | |
99 | void * | | 99 | void * |
100 | nonnull(void *p) | | 100 | nonnull(void *p) |
101 | { | | 101 | { |
102 | if (p == NULL) | | 102 | if (p == NULL) |
103 | err(EXIT_FAILURE, NULL); | | 103 | err(EXIT_FAILURE, NULL); |
104 | return p; | | 104 | return p; |
105 | } | | 105 | } |
106 | | | 106 | |
107 | static void | | 107 | static void |
108 | buf_expand(struct buffer *buf, size_t add_size) | | 108 | buf_expand(struct buffer *buf, size_t add_size) |
109 | { | | 109 | { |
110 | buf->cap = buf->cap + add_size + 400; | | 110 | buf->cap = buf->cap + add_size + 400; |
111 | buf->s = nonnull(realloc(buf->s, buf->cap)); | | 111 | buf->s = nonnull(realloc(buf->s, buf->cap)); |
112 | } | | 112 | } |
113 | | | 113 | |
114 | #ifdef debug | | 114 | #ifdef debug |
115 | void | | 115 | void |
116 | buf_terminate(struct buffer *buf) | | 116 | buf_terminate(struct buffer *buf) |
117 | { | | 117 | { |
118 | if (buf->len == buf->cap) | | 118 | if (buf->len == buf->cap) |
119 | buf_expand(buf, 1); | | 119 | buf_expand(buf, 1); |
120 | buf->s[buf->len] = '\0'; | | 120 | buf->s[buf->len] = '\0'; |
121 | } | | 121 | } |
122 | #endif | | 122 | #endif |
123 | | | 123 | |
124 | void | | 124 | void |
125 | buf_add_char(struct buffer *buf, char ch) | | 125 | buf_add_char(struct buffer *buf, char ch) |
126 | { | | 126 | { |
127 | if (buf->len == buf->cap) | | 127 | if (buf->len == buf->cap) |
128 | buf_expand(buf, 1); | | 128 | buf_expand(buf, 1); |
129 | buf->s[buf->len++] = ch; | | 129 | buf->s[buf->len++] = ch; |
130 | buf_terminate(buf); | | 130 | buf_terminate(buf); |
131 | } | | 131 | } |
132 | | | 132 | |
133 | void | | 133 | void |
134 | buf_add_chars(struct buffer *buf, const char *s, size_t len) | | 134 | buf_add_chars(struct buffer *buf, const char *s, size_t len) |
135 | { | | 135 | { |
136 | if (len == 0) | | 136 | if (len == 0) |
137 | return; | | 137 | return; |
138 | if (len > buf->cap - buf->len) | | 138 | if (len > buf->cap - buf->len) |
139 | buf_expand(buf, len); | | 139 | buf_expand(buf, len); |
140 | memcpy(buf->s + buf->len, s, len); | | 140 | memcpy(buf->s + buf->len, s, len); |
141 | buf->len += len; | | 141 | buf->len += len; |
142 | buf_terminate(buf); | | 142 | buf_terminate(buf); |
143 | } | | 143 | } |
144 | | | 144 | |
145 | static void | | 145 | static void |
146 | buf_add_buf(struct buffer *buf, const struct buffer *add) | | 146 | buf_add_buf(struct buffer *buf, const struct buffer *add) |
147 | { | | 147 | { |
148 | buf_add_chars(buf, add->s, add->len); | | 148 | buf_add_chars(buf, add->s, add->len); |
149 | } | | 149 | } |
150 | | | 150 | |
151 | void | | 151 | void |
152 | diag(int level, const char *msg, ...) | | 152 | diag(int level, const char *msg, ...) |
153 | { | | 153 | { |
154 | va_list ap; | | 154 | va_list ap; |
155 | | | 155 | |
156 | if (level != 0) | | 156 | if (level != 0) |
157 | found_err = true; | | 157 | found_err = true; |
158 | | | 158 | |
159 | va_start(ap, msg); | | 159 | va_start(ap, msg); |
160 | fprintf(stderr, "%s: %s:%d: ", | | 160 | fprintf(stderr, "%s: %s:%d: ", |
161 | level == 0 ? "warning" : "error", in_name, line_no); | | 161 | level == 0 ? "warning" : "error", in_name, line_no); |
162 | vfprintf(stderr, msg, ap); | | 162 | vfprintf(stderr, msg, ap); |
163 | fprintf(stderr, "\n"); | | 163 | fprintf(stderr, "\n"); |
164 | va_end(ap); | | 164 | va_end(ap); |
165 | } | | 165 | } |
166 | | | 166 | |
167 | /* | | 167 | /* |
168 | * Compute the indentation from starting at 'ind' and adding the text starting | | 168 | * Compute the indentation from starting at 'ind' and adding the text starting |
169 | * at 's'. | | 169 | * at 's'. |
170 | */ | | 170 | */ |
171 | int | | 171 | int |
172 | ind_add(int ind, const char *s, size_t len) | | 172 | ind_add(int ind, const char *s, size_t len) |
173 | { | | 173 | { |
174 | for (const char *p = s; len > 0; p++, len--) { | | 174 | for (const char *p = s; len > 0; p++, len--) { |
175 | if (*p == '\n') | | 175 | if (*p == '\n') |
176 | ind = 0; | | 176 | ind = 0; |
177 | else if (*p == '\t') | | 177 | else if (*p == '\t') |
178 | ind = next_tab(ind); | | 178 | ind = next_tab(ind); |
179 | else if (*p == '\b') | | 179 | else if (*p == '\b') |
180 | --ind; | | 180 | --ind; |
181 | else | | 181 | else |
182 | ++ind; | | 182 | ++ind; |
183 | } | | 183 | } |
184 | return ind; | | 184 | return ind; |
185 | } | | 185 | } |
186 | | | 186 | |
187 | static void | | 187 | static void |
188 | init_globals(void) | | 188 | init_globals(void) |
189 | { | | 189 | { |
190 | ps_push(psym_stmt, false); /* as a stop symbol */ | | 190 | ps_push(psym_stmt, false); /* as a stop symbol */ |
191 | ps.prev_lsym = lsym_semicolon; | | 191 | ps.prev_lsym = lsym_semicolon; |
192 | ps.lbrace_kind = psym_lbrace_block; | | 192 | ps.lbrace_kind = psym_lbrace_block; |
193 | | | 193 | |
194 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | | 194 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); |
195 | if (suffix != NULL) | | 195 | if (suffix != NULL) |
196 | backup_suffix = suffix; | | 196 | backup_suffix = suffix; |
197 | } | | 197 | } |
198 | | | 198 | |
199 | static void | | 199 | static void |
200 | load_profiles(int argc, char **argv) | | 200 | load_profiles(int argc, char **argv) |
201 | { | | 201 | { |
202 | const char *profile_name = NULL; | | 202 | const char *profile_name = NULL; |
203 | | | 203 | |
204 | for (int i = 1; i < argc; ++i) { | | 204 | for (int i = 1; i < argc; ++i) { |
205 | const char *arg = argv[i]; | | 205 | const char *arg = argv[i]; |
206 | | | 206 | |
207 | if (strcmp(arg, "-npro") == 0) | | 207 | if (strcmp(arg, "-npro") == 0) |
208 | return; | | 208 | return; |
209 | if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0') | | 209 | if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0') |
210 | profile_name = arg + 2; | | 210 | profile_name = arg + 2; |
211 | } | | 211 | } |
212 | | | 212 | |
213 | load_profile_files(profile_name); | | 213 | load_profile_files(profile_name); |
214 | } | | 214 | } |
215 | | | 215 | |
216 | /* | | 216 | /* |
217 | * Copy the input file to the backup file, then make the backup file the input | | 217 | * Copy the input file to the backup file, then make the backup file the input |
218 | * and the original input file the output. | | 218 | * and the original input file the output. |
219 | */ | | 219 | */ |
220 | static void | | 220 | static void |
221 | copy_to_bak_file(void) | | 221 | copy_to_bak_file(void) |
222 | { | | 222 | { |
223 | size_t n; | | 223 | size_t n; |
224 | char buff[BUFSIZ]; | | 224 | char buff[BUFSIZ]; |
225 | | | 225 | |
226 | const char *last_slash = strrchr(in_name, '/'); | | 226 | const char *last_slash = strrchr(in_name, '/'); |
227 | const char *base = last_slash != NULL ? last_slash + 1 : in_name; | | 227 | const char *base = last_slash != NULL ? last_slash + 1 : in_name; |
228 | snprintf(backup_name, sizeof(backup_name), "%s%s", base, backup_suffix); | | 228 | snprintf(backup_name, sizeof(backup_name), "%s%s", base, backup_suffix); |
229 | | | 229 | |
230 | /* copy the input file to the backup file */ | | 230 | /* copy the input file to the backup file */ |
231 | FILE *bak = fopen(backup_name, "w"); | | 231 | FILE *bak = fopen(backup_name, "w"); |
232 | if (bak == NULL) | | 232 | if (bak == NULL) |
233 | err(1, "%s", backup_name); | | 233 | err(1, "%s", backup_name); |
234 | | | 234 | |
235 | while ((n = fread(buff, 1, sizeof(buff), input)) > 0) | | 235 | while ((n = fread(buff, 1, sizeof(buff), input)) > 0) |
236 | if (fwrite(buff, 1, n, bak) != n) | | 236 | if (fwrite(buff, 1, n, bak) != n) |
237 | err(1, "%s", backup_name); | | 237 | err(1, "%s", backup_name); |
238 | if (fclose(input) != 0) | | 238 | if (fclose(input) != 0) |
239 | err(1, "%s", in_name); | | 239 | err(1, "%s", in_name); |
240 | if (fclose(bak) != 0) | | 240 | if (fclose(bak) != 0) |
241 | err(1, "%s", backup_name); | | 241 | err(1, "%s", backup_name); |
242 | | | 242 | |
243 | /* re-open the backup file as the input file */ | | 243 | /* re-open the backup file as the input file */ |
244 | input = fopen(backup_name, "r"); | | 244 | input = fopen(backup_name, "r"); |
245 | if (input == NULL) | | 245 | if (input == NULL) |
246 | err(1, "%s", backup_name); | | 246 | err(1, "%s", backup_name); |
247 | /* now the original input file will be the output */ | | 247 | /* now the original input file will be the output */ |
248 | output = fopen(in_name, "w"); | | 248 | output = fopen(in_name, "w"); |
249 | if (output == NULL) { | | 249 | if (output == NULL) { |
250 | remove(backup_name); | | 250 | remove(backup_name); |
251 | err(1, "%s", in_name); | | 251 | err(1, "%s", in_name); |
252 | } | | 252 | } |
253 | } | | 253 | } |
254 | | | 254 | |
255 | static void | | 255 | static void |
256 | parse_command_line(int argc, char **argv) | | 256 | parse_command_line(int argc, char **argv) |
257 | { | | 257 | { |
258 | for (int i = 1; i < argc; ++i) { | | 258 | for (int i = 1; i < argc; ++i) { |
259 | const char *arg = argv[i]; | | 259 | const char *arg = argv[i]; |
260 | | | 260 | |
261 | if (arg[0] == '-') { | | 261 | if (arg[0] == '-') { |
262 | set_option(arg, "Command line"); | | 262 | set_option(arg, "Command line"); |
263 | | | 263 | |
264 | } else if (input == NULL) { | | 264 | } else if (input == NULL) { |
265 | in_name = arg; | | 265 | in_name = arg; |
266 | if ((input = fopen(in_name, "r")) == NULL) | | 266 | if ((input = fopen(in_name, "r")) == NULL) |
267 | err(1, "%s", in_name); | | 267 | err(1, "%s", in_name); |
268 | | | 268 | |
269 | } else if (output == NULL) { | | 269 | } else if (output == NULL) { |
270 | if (strcmp(arg, in_name) == 0) | | 270 | if (strcmp(arg, in_name) == 0) |
271 | errx(1, "input and output files " | | 271 | errx(1, "input and output files " |
272 | "must be different"); | | 272 | "must be different"); |
273 | if ((output = fopen(arg, "w")) == NULL) | | 273 | if ((output = fopen(arg, "w")) == NULL) |
274 | err(1, "%s", arg); | | 274 | err(1, "%s", arg); |
275 | | | 275 | |
276 | } else | | 276 | } else |
277 | errx(1, "too many arguments: %s", arg); | | 277 | errx(1, "too many arguments: %s", arg); |
278 | } | | 278 | } |
279 | | | 279 | |
280 | if (input == NULL) { | | 280 | if (input == NULL) { |
281 | input = stdin; | | 281 | input = stdin; |
282 | output = stdout; | | 282 | output = stdout; |
283 | } else if (output == NULL) | | 283 | } else if (output == NULL) |
284 | copy_to_bak_file(); | | 284 | copy_to_bak_file(); |
285 | | | 285 | |
286 | if (opt.comment_column <= 1) | | 286 | if (opt.comment_column <= 1) |
287 | opt.comment_column = 2; /* don't put normal comments in column | | 287 | opt.comment_column = 2; /* don't put normal comments in column |
288 | * 1, see opt.format_col1_comments */ | | 288 | * 1, see opt.format_col1_comments */ |
289 | if (opt.block_comment_max_line_length <= 0) | | 289 | if (opt.block_comment_max_line_length <= 0) |
290 | opt.block_comment_max_line_length = opt.max_line_length; | | 290 | opt.block_comment_max_line_length = opt.max_line_length; |
291 | if (opt.local_decl_indent < 0) | | 291 | if (opt.local_decl_indent < 0) |
292 | opt.local_decl_indent = opt.decl_indent; | | 292 | opt.local_decl_indent = opt.decl_indent; |
293 | if (opt.decl_comment_column <= 0) | | 293 | if (opt.decl_comment_column <= 0) |
294 | opt.decl_comment_column = opt.left_justify_decl | | 294 | opt.decl_comment_column = opt.left_justify_decl |
295 | ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) | | 295 | ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) |
296 | : opt.comment_column; | | 296 | : opt.comment_column; |
297 | if (opt.continuation_indent == 0) | | 297 | if (opt.continuation_indent == 0) |
298 | opt.continuation_indent = opt.indent_size; | | 298 | opt.continuation_indent = opt.indent_size; |
299 | } | | 299 | } |
300 | | | 300 | |
301 | static void | | 301 | static void |
302 | set_initial_indentation(void) | | 302 | set_initial_indentation(void) |
303 | { | | 303 | { |
304 | inp_read_line(); | | 304 | inp_read_line(); |
305 | | | 305 | |
306 | int ind = 0; | | 306 | int ind = 0; |
307 | for (const char *p = inp_p;; p++) { | | 307 | for (const char *p = inp_p;; p++) { |
308 | if (*p == ' ') | | 308 | if (*p == ' ') |
309 | ind++; | | 309 | ind++; |
310 | else if (*p == '\t') | | 310 | else if (*p == '\t') |
311 | ind = next_tab(ind); | | 311 | ind = next_tab(ind); |
312 | else | | 312 | else |
313 | break; | | 313 | break; |
314 | } | | 314 | } |
315 | | | 315 | |
316 | ps.ind_level = ps.ind_level_follow = ind / opt.indent_size; | | 316 | ps.ind_level = ps.ind_level_follow = ind / opt.indent_size; |
317 | } | | 317 | } |
318 | | | 318 | |
319 | static bool | | 319 | static bool |
320 | should_break_line(lexer_symbol lsym) | | 320 | should_break_line(lexer_symbol lsym) |
321 | { | | 321 | { |
322 | if (lsym == lsym_semicolon) | | 322 | if (lsym == lsym_semicolon) |
323 | return false; | | 323 | return false; |
324 | if (ps.prev_lsym == lsym_lbrace || ps.prev_lsym == lsym_semicolon) | | 324 | if (ps.prev_lsym == lsym_lbrace || ps.prev_lsym == lsym_semicolon) |
325 | return true; | | 325 | return true; |
326 | if (lsym == lsym_lbrace && opt.brace_same_line) | | 326 | if (lsym == lsym_lbrace && opt.brace_same_line) |
327 | return false; | | 327 | return false; |
328 | return true; | | 328 | return true; |
329 | } | | 329 | } |
330 | | | 330 | |
331 | static void | | 331 | static void |
332 | move_com_to_code(lexer_symbol lsym) | | 332 | move_com_to_code(lexer_symbol lsym) |
333 | { | | 333 | { |
334 | if (ps.want_blank) | | 334 | if (ps.want_blank) |
335 | buf_add_char(&code, ' '); | | 335 | buf_add_char(&code, ' '); |
336 | buf_add_buf(&code, &com); | | 336 | buf_add_buf(&code, &com); |
337 | buf_clear(&com); | | 337 | buf_clear(&com); |
338 | ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; | | 338 | ps.want_blank = lsym != lsym_rparen && lsym != lsym_rbracket; |
339 | } | | 339 | } |
340 | | | 340 | |
341 | static void | | 341 | static void |
342 | update_ps_lbrace_kind(lexer_symbol lsym) | | 342 | update_ps_lbrace_kind(lexer_symbol lsym) |
343 | { | | 343 | { |
344 | if (lsym == lsym_tag) { | | 344 | if (lsym == lsym_tag) { |
345 | ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : | | 345 | ps.lbrace_kind = token.s[0] == 's' ? psym_lbrace_struct : |
346 | token.s[0] == 'u' ? psym_lbrace_union : | | 346 | token.s[0] == 'u' ? psym_lbrace_union : |
347 | psym_lbrace_enum; | | 347 | psym_lbrace_enum; |
348 | } else if (lsym == lsym_type_outside_parentheses | | 348 | } else if (lsym == lsym_type_outside_parentheses |
349 | || lsym == lsym_word | | 349 | || lsym == lsym_word |
350 | || lsym == lsym_lbrace) { | | 350 | || lsym == lsym_lbrace) { |
351 | /* Keep the current '{' kind. */ | | 351 | /* Keep the current '{' kind. */ |
352 | } else | | 352 | } else |
353 | ps.lbrace_kind = psym_lbrace_block; | | 353 | ps.lbrace_kind = psym_lbrace_block; |
354 | } | | 354 | } |
355 | | | 355 | |
356 | static void | | 356 | static void |
357 | indent_declarator(int decl_ind, bool tabs_to_var) | | 357 | indent_declarator(int decl_ind, bool tabs_to_var) |
358 | { | | 358 | { |
359 | int base = ps.ind_level * opt.indent_size; | | 359 | int base = ps.ind_level * opt.indent_size; |
360 | int ind = ind_add(base, code.s, code.len); | | 360 | int ind = ind_add(base, code.s, code.len); |
361 | int target = base + decl_ind; | | 361 | int target = base + decl_ind; |
362 | size_t orig_code_len = code.len; | | 362 | size_t orig_code_len = code.len; |
363 | | | 363 | |
364 | if (tabs_to_var) | | 364 | if (tabs_to_var) |
365 | for (int next; (next = next_tab(ind)) <= target; ind = next) | | 365 | for (int next; (next = next_tab(ind)) <= target; ind = next) |
366 | buf_add_char(&code, '\t'); | | 366 | buf_add_char(&code, '\t'); |
367 | for (; ind < target; ind++) | | 367 | for (; ind < target; ind++) |
368 | buf_add_char(&code, ' '); | | 368 | buf_add_char(&code, ' '); |
369 | if (code.len == orig_code_len && ps.want_blank) | | 369 | if (code.len == orig_code_len && ps.want_blank) |
370 | buf_add_char(&code, ' '); | | 370 | buf_add_char(&code, ' '); |
371 | | | 371 | |
372 | ps.want_blank = false; | | 372 | ps.want_blank = false; |
373 | ps.decl_indent_done = true; | | 373 | ps.decl_indent_done = true; |
374 | } | | 374 | } |
375 | | | 375 | |
376 | static bool | | 376 | static bool |
377 | is_function_pointer_declaration(void) | | 377 | is_function_pointer_declaration(void) |
378 | { | | 378 | { |
379 | return ps.in_decl | | 379 | return ps.in_decl |
380 | && !ps.in_typedef_decl | | 380 | && !ps.in_typedef_decl |
381 | && !ps.in_init | | 381 | && !ps.in_init |
382 | && !ps.decl_indent_done | | 382 | && !ps.decl_indent_done |
383 | && !ps.line_has_func_def | | 383 | && !ps.line_has_func_def |
384 | && ps.ind_paren_level == 0; | | 384 | && ps.ind_paren_level == 0; |
385 | } | | 385 | } |
386 | | | 386 | |
387 | static int | | 387 | static int |
388 | process_eof(void) | | 388 | process_eof(void) |
389 | { | | 389 | { |
390 | finish_output(); | | 390 | finish_output(); |
391 | | | 391 | |
392 | if (ps.psyms.len > 2) /* check for balanced braces */ | | 392 | if (ps.psyms.len > 2) /* check for balanced braces */ |
393 | diag(1, "Stuff missing from end of file"); | | 393 | diag(1, "Stuff missing from end of file"); |
394 | | | 394 | |
395 | return found_err ? EXIT_FAILURE : EXIT_SUCCESS; | | 395 | return found_err ? EXIT_FAILURE : EXIT_SUCCESS; |
396 | } | | 396 | } |
397 | | | 397 | |
398 | /* move the whole line to the 'label' buffer */ | | 398 | /* move the whole line to the 'label' buffer */ |
399 | static void | | 399 | static void |
400 | read_preprocessing_line(void) | | 400 | read_preprocessing_line(void) |
401 | { | | 401 | { |
402 | enum { | | 402 | enum { |
403 | PLAIN, STR, CHR, COMM | | 403 | PLAIN, STR, CHR, COMM |
404 | } state = PLAIN; | | 404 | } state = PLAIN; |
405 | | | 405 | |
406 | buf_add_char(&lab, '#'); | | 406 | buf_add_char(&lab, '#'); |
407 | | | 407 | |
408 | while (inp_p[0] != '\n' || (state == COMM && !had_eof)) { | | 408 | while (inp_p[0] != '\n' || (state == COMM && !had_eof)) { |
409 | buf_add_char(&lab, inp_next()); | | 409 | buf_add_char(&lab, inp_next()); |
410 | switch (lab.s[lab.len - 1]) { | | 410 | switch (lab.s[lab.len - 1]) { |
411 | case '\\': | | 411 | case '\\': |
412 | if (state != COMM) | | 412 | if (state != COMM) |
413 | buf_add_char(&lab, inp_next()); | | 413 | buf_add_char(&lab, inp_next()); |
414 | break; | | 414 | break; |
415 | case '/': | | 415 | case '/': |
416 | if (inp_p[0] == '*' && state == PLAIN) { | | 416 | if (inp_p[0] == '*' && state == PLAIN) { |
417 | state = COMM; | | 417 | state = COMM; |
418 | buf_add_char(&lab, *inp_p++); | | 418 | buf_add_char(&lab, *inp_p++); |
419 | } | | 419 | } |
420 | break; | | 420 | break; |
421 | case '"': | | 421 | case '"': |
422 | if (state == STR) | | 422 | if (state == STR) |
423 | state = PLAIN; | | 423 | state = PLAIN; |
424 | else if (state == PLAIN) | | 424 | else if (state == PLAIN) |
425 | state = STR; | | 425 | state = STR; |
426 | break; | | 426 | break; |
427 | case '\'': | | 427 | case '\'': |
428 | if (state == CHR) | | 428 | if (state == CHR) |
429 | state = PLAIN; | | 429 | state = PLAIN; |
430 | else if (state == PLAIN) | | 430 | else if (state == PLAIN) |
431 | state = CHR; | | 431 | state = CHR; |
432 | break; | | 432 | break; |
433 | case '*': | | 433 | case '*': |
434 | if (inp_p[0] == '/' && state == COMM) { | | 434 | if (inp_p[0] == '/' && state == COMM) { |
435 | state = PLAIN; | | 435 | state = PLAIN; |
436 | buf_add_char(&lab, *inp_p++); | | 436 | buf_add_char(&lab, *inp_p++); |
437 | } | | 437 | } |
438 | break; | | 438 | break; |
439 | } | | 439 | } |
440 | } | | 440 | } |
441 | | | 441 | |
442 | while (lab.len > 0 && ch_isblank(lab.s[lab.len - 1])) | | 442 | while (lab.len > 0 && ch_isblank(lab.s[lab.len - 1])) |
443 | lab.len--; | | 443 | lab.len--; |
444 | buf_terminate(&lab); | | 444 | buf_terminate(&lab); |
445 | } | | 445 | } |
446 | | | 446 | |
447 | static void | | 447 | static void |
448 | paren_stack_push(struct paren_stack *s, int indent, enum paren_level_cast cast) | | 448 | paren_stack_push(struct paren_stack *s, int indent, enum paren_level_cast cast) |
449 | { | | 449 | { |
450 | if (s->len == s->cap) { | | 450 | if (s->len == s->cap) { |
451 | s->cap = 10 + s->cap; | | 451 | s->cap = 10 + s->cap; |
452 | s->item = nonnull(realloc(s->item, | | 452 | s->item = nonnull(realloc(s->item, |
453 | sizeof(s->item[0]) * s->cap)); | | 453 | sizeof(s->item[0]) * s->cap)); |
454 | } | | 454 | } |
455 | s->item[s->len++] = (struct paren_level){indent, cast}; | | 455 | s->item[s->len++] = (struct paren_level){indent, cast}; |
456 | } | | 456 | } |
457 | | | 457 | |
458 | static void * | | 458 | static void * |
459 | dup_mem(const void *src, size_t size) | | 459 | dup_mem(const void *src, size_t size) |
460 | { | | 460 | { |
461 | return memcpy(nonnull(malloc(size)), src, size); | | 461 | return memcpy(nonnull(malloc(size)), src, size); |
462 | } | | 462 | } |
463 | | | 463 | |
464 | #define dup_array(src, len) \ | | 464 | #define dup_array(src, len) \ |
465 | dup_mem((src), sizeof((src)[0]) * (len)) | | 465 | dup_mem((src), sizeof((src)[0]) * (len)) |
466 | #define copy_array(dst, src, len) \ | | 466 | #define copy_array(dst, src, len) \ |
467 | memcpy((dst), (src), sizeof((dst)[0]) * (len)) | | 467 | memcpy((dst), (src), sizeof((dst)[0]) * (len)) |
468 | | | 468 | |
469 | static void | | 469 | static void |
470 | parser_state_back_up(struct parser_state *dst) | | 470 | parser_state_back_up(struct parser_state *dst) |
471 | { | | 471 | { |
472 | *dst = ps; | | 472 | *dst = ps; |
473 | | | 473 | |
474 | dst->paren.item = dup_array(ps.paren.item, ps.paren.len); | | 474 | dst->paren.item = dup_array(ps.paren.item, ps.paren.len); |
475 | dst->psyms.sym = dup_array(ps.psyms.sym, ps.psyms.len); | | 475 | dst->psyms.sym = dup_array(ps.psyms.sym, ps.psyms.len); |
476 | dst->psyms.ind_level = dup_array(ps.psyms.ind_level, ps.psyms.len); | | 476 | dst->psyms.ind_level = dup_array(ps.psyms.ind_level, ps.psyms.len); |
477 | } | | 477 | } |
478 | | | 478 | |
479 | static void | | 479 | static void |
480 | parser_state_restore(const struct parser_state *src) | | 480 | parser_state_restore(const struct parser_state *src) |
481 | { | | 481 | { |
482 | struct paren_level *ps_paren_item = ps.paren.item; | | 482 | struct paren_level *ps_paren_item = ps.paren.item; |
483 | size_t ps_paren_cap = ps.paren.cap; | | 483 | size_t ps_paren_cap = ps.paren.cap; |
484 | enum parser_symbol *ps_psyms_sym = ps.psyms.sym; | | 484 | enum parser_symbol *ps_psyms_sym = ps.psyms.sym; |
485 | int *ps_psyms_ind_level = ps.psyms.ind_level; | | 485 | int *ps_psyms_ind_level = ps.psyms.ind_level; |
486 | size_t ps_psyms_cap = ps.psyms.cap; | | 486 | size_t ps_psyms_cap = ps.psyms.cap; |
487 | | | 487 | |
488 | ps = *src; | | 488 | ps = *src; |
489 | | | 489 | |
490 | ps.paren.item = ps_paren_item; | | 490 | ps.paren.item = ps_paren_item; |
491 | ps.paren.cap = ps_paren_cap; | | 491 | ps.paren.cap = ps_paren_cap; |
492 | ps.psyms.sym = ps_psyms_sym; | | 492 | ps.psyms.sym = ps_psyms_sym; |
493 | ps.psyms.ind_level = ps_psyms_ind_level; | | 493 | ps.psyms.ind_level = ps_psyms_ind_level; |
494 | ps.psyms.cap = ps_psyms_cap; | | 494 | ps.psyms.cap = ps_psyms_cap; |
495 | | | 495 | |
496 | copy_array(ps.paren.item, src->paren.item, src->paren.len); | | 496 | copy_array(ps.paren.item, src->paren.item, src->paren.len); |
497 | copy_array(ps.psyms.sym, src->psyms.sym, src->psyms.len); | | 497 | copy_array(ps.psyms.sym, src->psyms.sym, src->psyms.len); |
498 | copy_array(ps.psyms.ind_level, src->psyms.ind_level, src->psyms.len); | | 498 | copy_array(ps.psyms.ind_level, src->psyms.ind_level, src->psyms.len); |
499 | } | | 499 | } |
500 | | | 500 | |
501 | static void | | 501 | static void |
502 | parser_state_free(struct parser_state *pst) | | 502 | parser_state_free(struct parser_state *pst) |
503 | { | | 503 | { |
504 | free(pst->paren.item); | | 504 | free(pst->paren.item); |
505 | free(pst->psyms.sym); | | 505 | free(pst->psyms.sym); |
506 | free(pst->psyms.ind_level); | | 506 | free(pst->psyms.ind_level); |
507 | } | | 507 | } |
508 | | | 508 | |
509 | static void | | 509 | static void |
510 | process_preprocessing(void) | | 510 | process_preprocessing(void) |
511 | { | | 511 | { |
512 | if (lab.len > 0 || code.len > 0 || com.len > 0) | | 512 | if (lab.len > 0 || code.len > 0 || com.len > 0) |
513 | output_line(); | | 513 | output_line(); |
514 | | | 514 | |
515 | read_preprocessing_line(); | | 515 | read_preprocessing_line(); |
516 | | | 516 | |
517 | const char *dir = lab.s + 1, *line_end = lab.s + lab.len; | | 517 | const char *dir = lab.s + 1, *line_end = lab.s + lab.len; |
518 | while (dir < line_end && ch_isblank(*dir)) | | 518 | while (dir < line_end && ch_isblank(*dir)) |
519 | dir++; | | 519 | dir++; |
520 | size_t dir_len = 0; | | 520 | size_t dir_len = 0; |
521 | while (dir + dir_len < line_end && ch_isalpha(dir[dir_len])) | | 521 | while (dir + dir_len < line_end && ch_isalpha(dir[dir_len])) |
522 | dir_len++; | | 522 | dir_len++; |
523 | | | 523 | |
524 | if (dir_len >= 2 && memcmp(dir, "if", 2) == 0) { | | 524 | if (dir_len >= 2 && memcmp(dir, "if", 2) == 0) { |
525 | if (ifdef.len >= ifdef.cap) { | | 525 | if (ifdef.len >= ifdef.cap) { |
526 | ifdef.cap += 5; | | 526 | ifdef.cap += 5; |
527 | ifdef.item = nonnull(realloc(ifdef.item, | | 527 | ifdef.item = nonnull(realloc(ifdef.item, |
528 | sizeof(ifdef.item[0]) * ifdef.cap)); | | 528 | sizeof(ifdef.item[0]) * ifdef.cap)); |
529 | } | | 529 | } |
530 | parser_state_back_up(ifdef.item + ifdef.len++); | | 530 | parser_state_back_up(ifdef.item + ifdef.len++); |
531 | out.line_kind = lk_pre_if; | | 531 | out.line_kind = lk_pre_if; |
532 | | | 532 | |
533 | } else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) { | | 533 | } else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) { |
534 | if (ifdef.len == 0) | | 534 | if (ifdef.len == 0) |
535 | diag(1, "Unmatched #%.*s", (int)dir_len, dir); | | 535 | diag(1, "Unmatched #%.*s", (int)dir_len, dir); |
536 | else | | 536 | else |
537 | parser_state_restore(ifdef.item + ifdef.len - 1); | | 537 | parser_state_restore(ifdef.item + ifdef.len - 1); |
538 | out.line_kind = lk_pre_other; | | 538 | out.line_kind = lk_pre_other; |
539 | | | 539 | |
540 | } else if (dir_len == 5 && memcmp(dir, "endif", 5) == 0) { | | 540 | } else if (dir_len == 5 && memcmp(dir, "endif", 5) == 0) { |
541 | if (ifdef.len == 0) | | 541 | if (ifdef.len == 0) |
542 | diag(1, "Unmatched #endif"); | | 542 | diag(1, "Unmatched #endif"); |
543 | else | | 543 | else |
544 | parser_state_free(ifdef.item + --ifdef.len); | | 544 | parser_state_free(ifdef.item + --ifdef.len); |
545 | out.line_kind = lk_pre_endif; | | 545 | out.line_kind = lk_pre_endif; |
546 | } else | | 546 | } else |
547 | out.line_kind = lk_pre_other; | | 547 | out.line_kind = lk_pre_other; |
548 | } | | 548 | } |
549 | | | 549 | |
550 | static void | | 550 | static void |
551 | process_newline(void) | | 551 | process_newline(void) |
552 | { | | 552 | { |
553 | if (ps.prev_lsym == lsym_comma | | 553 | if (ps.prev_lsym == lsym_comma |
554 | && ps.paren.len == 0 && !ps.in_init | | 554 | && ps.paren.len == 0 && !ps.in_init |
555 | && !opt.break_after_comma && ps.break_after_comma | | 555 | && !opt.break_after_comma && ps.break_after_comma |
556 | && lab.len == 0 /* for preprocessing lines */ | | 556 | && lab.len == 0 /* for preprocessing lines */ |
557 | && com.len == 0) | | 557 | && com.len == 0) |
558 | goto stay_in_line; | | 558 | goto stay_in_line; |
559 | if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr | | 559 | if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr |
560 | && opt.brace_same_line | | 560 | && opt.brace_same_line |
561 | && com.len == 0) { | | 561 | && com.len == 0) { |
562 | ps.want_newline = true; | | 562 | ps.want_newline = true; |
563 | goto stay_in_line; | | 563 | goto stay_in_line; |
564 | } | | 564 | } |
565 | | | 565 | |
566 | output_line(); | | 566 | output_line(); |
567 | | | 567 | |
568 | stay_in_line: | | 568 | stay_in_line: |
569 | ++line_no; | | 569 | ++line_no; |
570 | } | | 570 | } |
571 | | | 571 | |
572 | static bool | | 572 | static bool |
573 | want_blank_before_lparen(void) | | 573 | want_blank_before_lparen(void) |
574 | { | | 574 | { |
575 | if (opt.proc_calls_space) | | 575 | if (opt.proc_calls_space) |
576 | return true; | | 576 | return true; |
577 | if (ps.prev_lsym == lsym_rparen || ps.prev_lsym == lsym_rbracket) | | 577 | if (ps.prev_lsym == lsym_rparen || ps.prev_lsym == lsym_rbracket) |
578 | return false; | | 578 | return false; |
579 | if (ps.prev_lsym == lsym_offsetof) | | 579 | if (ps.prev_lsym == lsym_offsetof) |
580 | return false; | | 580 | return false; |
581 | if (ps.prev_lsym == lsym_sizeof) | | 581 | if (ps.prev_lsym == lsym_sizeof) |
582 | return opt.blank_after_sizeof; | | 582 | return opt.blank_after_sizeof; |
583 | if (ps.prev_lsym == lsym_word || ps.prev_lsym == lsym_funcname) | | 583 | if (ps.prev_lsym == lsym_word || ps.prev_lsym == lsym_funcname) |
584 | return false; | | 584 | return false; |
585 | return true; | | 585 | return true; |
586 | } | | 586 | } |
587 | | | 587 | |
588 | static void | | 588 | static void |
589 | process_lparen(void) | | 589 | process_lparen(void) |
590 | { | | 590 | { |
591 | | | 591 | |
592 | if (is_function_pointer_declaration()) | | 592 | if (is_function_pointer_declaration()) |
593 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | | 593 | indent_declarator(ps.decl_ind, ps.tabs_to_var); |
594 | else if (ps.want_blank && want_blank_before_lparen()) | | 594 | else if (ps.want_blank && want_blank_before_lparen()) |
595 | buf_add_char(&code, ' '); | | 595 | buf_add_char(&code, ' '); |
596 | ps.want_blank = false; | | 596 | ps.want_blank = false; |
597 | buf_add_buf(&code, &token); | | 597 | buf_add_buf(&code, &token); |
598 | | | 598 | |
599 | if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) | | 599 | if (opt.extra_expr_indent && ps.spaced_expr_psym != psym_0) |
600 | ps.extra_expr_indent = eei_maybe; | | 600 | ps.extra_expr_indent = eei_maybe; |
601 | | | 601 | |
602 | if (ps.in_var_decl && ps.psyms.len <= 3 && !ps.in_init) { | | 602 | if (ps.in_var_decl && ps.psyms.len <= 3 && !ps.in_init) { |
603 | parse(psym_stmt); /* prepare for function definition */ | | 603 | parse(psym_stmt); /* prepare for function definition */ |
604 | ps.in_var_decl = false; | | 604 | ps.in_var_decl = false; |
605 | } | | 605 | } |
606 | | | 606 | |
607 | enum paren_level_cast cast = cast_unknown; | | 607 | enum paren_level_cast cast = cast_unknown; |
608 | if (ps.prev_lsym == lsym_offsetof | | 608 | if (ps.prev_lsym == lsym_offsetof |
609 | || ps.prev_lsym == lsym_sizeof | | 609 | || ps.prev_lsym == lsym_sizeof |
610 | || ps.prev_lsym == lsym_for | | 610 | || ps.prev_lsym == lsym_for |
611 | || ps.prev_lsym == lsym_if | | 611 | || ps.prev_lsym == lsym_if |
612 | || ps.prev_lsym == lsym_switch | | 612 | || ps.prev_lsym == lsym_switch |
613 | || ps.prev_lsym == lsym_while | | 613 | || ps.prev_lsym == lsym_while |
614 | || ps.line_has_func_def) | | 614 | || ps.line_has_func_def) |
615 | cast = cast_no; | | 615 | cast = cast_no; |
616 | | | 616 | |
617 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast); | | 617 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast); |
618 | } | | 618 | } |
619 | | | 619 | |
| | | 620 | static bool |
| | | 621 | rparen_is_cast(bool paren_cast) |
| | | 622 | { |
| | | 623 | if (ps.in_func_def_params) |
| | | 624 | return false; |
| | | 625 | if (ps.prev_lsym == lsym_unary_op) |
| | | 626 | return true; |
| | | 627 | if (ps.line_has_decl && !ps.in_init) |
| | | 628 | return false; |
| | | 629 | return paren_cast || ch_isalpha(inp_p[0]); |
| | | 630 | } |
| | | 631 | |
620 | static void | | 632 | static void |
621 | process_rparen(void) | | 633 | process_rparen(void) |
622 | { | | 634 | { |
623 | if (ps.paren.len == 0) | | 635 | if (ps.paren.len == 0) |
624 | diag(0, "Extra '%c'", *token.s); | | 636 | diag(0, "Extra '%c'", *token.s); |
625 | | | 637 | |
626 | ps.prev_paren_was_cast = ps.paren.len > 0 | | 638 | bool paren_cast = ps.paren.len > 0 |
627 | && ps.paren.item[--ps.paren.len].cast == cast_maybe | | 639 | && ps.paren.item[--ps.paren.len].cast == cast_maybe; |
628 | && !ps.in_func_def_params | | 640 | ps.prev_paren_was_cast = rparen_is_cast(paren_cast); |
629 | && !(ps.line_has_decl && !ps.in_init); | | | |
630 | if (ps.prev_lsym == lsym_unary_op) | | | |
631 | ps.prev_paren_was_cast = true; | | | |
632 | if (ps.prev_paren_was_cast) { | | 641 | if (ps.prev_paren_was_cast) { |
633 | ps.next_unary = true; | | 642 | ps.next_unary = true; |
634 | ps.want_blank = opt.space_after_cast; | | 643 | ps.want_blank = opt.space_after_cast; |
635 | } else | | 644 | } else |
636 | ps.want_blank = true; | | 645 | ps.want_blank = true; |
637 | | | 646 | |
638 | if (code.len == 0) | | 647 | if (code.len == 0) |
639 | ps.ind_paren_level = (int)ps.paren.len; | | 648 | ps.ind_paren_level = (int)ps.paren.len; |
640 | | | 649 | |
641 | buf_add_buf(&code, &token); | | 650 | buf_add_buf(&code, &token); |
642 | | | 651 | |
643 | if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { | | 652 | if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { |
644 | parse(ps.spaced_expr_psym); | | 653 | parse(ps.spaced_expr_psym); |
645 | ps.spaced_expr_psym = psym_0; | | 654 | ps.spaced_expr_psym = psym_0; |
646 | | | 655 | |
647 | ps.want_newline = true; | | 656 | ps.want_newline = true; |
648 | ps.next_unary = true; | | 657 | ps.next_unary = true; |
649 | ps.in_stmt_or_decl = false; | | 658 | ps.in_stmt_or_decl = false; |
650 | ps.want_blank = true; | | 659 | ps.want_blank = true; |
651 | out.line_kind = lk_stmt_head; | | 660 | out.line_kind = lk_stmt_head; |
652 | if (ps.extra_expr_indent == eei_maybe) | | 661 | if (ps.extra_expr_indent == eei_maybe) |
653 | ps.extra_expr_indent = eei_last; | | 662 | ps.extra_expr_indent = eei_last; |
654 | } | | 663 | } |
655 | } | | 664 | } |
656 | | | 665 | |
657 | static void | | 666 | static void |
658 | process_lbracket(void) | | 667 | process_lbracket(void) |
659 | { | | 668 | { |
660 | if (code.len > 0 | | 669 | if (code.len > 0 |
661 | && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) | | 670 | && (ps.prev_lsym == lsym_comma || ps.prev_lsym == lsym_binary_op)) |
662 | buf_add_char(&code, ' '); | | 671 | buf_add_char(&code, ' '); |
663 | buf_add_buf(&code, &token); | | 672 | buf_add_buf(&code, &token); |
664 | ps.want_blank = false; | | 673 | ps.want_blank = false; |
665 | | | 674 | |
666 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast_no); | | 675 | paren_stack_push(&ps.paren, ind_add(0, code.s, code.len), cast_no); |
667 | } | | 676 | } |
668 | | | 677 | |
669 | static void | | 678 | static void |
670 | process_rbracket(void) | | 679 | process_rbracket(void) |
671 | { | | 680 | { |
672 | if (ps.paren.len == 0) | | 681 | if (ps.paren.len == 0) |
673 | diag(0, "Extra '%c'", *token.s); | | 682 | diag(0, "Extra '%c'", *token.s); |
674 | if (ps.paren.len > 0) | | 683 | if (ps.paren.len > 0) |
675 | ps.paren.len--; | | 684 | ps.paren.len--; |
676 | | | 685 | |
677 | if (code.len == 0) | | 686 | if (code.len == 0) |
678 | ps.ind_paren_level = (int)ps.paren.len; | | 687 | ps.ind_paren_level = (int)ps.paren.len; |
679 | | | 688 | |
680 | buf_add_buf(&code, &token); | | 689 | buf_add_buf(&code, &token); |
681 | ps.want_blank = true; | | 690 | ps.want_blank = true; |
682 | } | | 691 | } |
683 | | | 692 | |
684 | static void | | 693 | static void |
685 | process_lbrace(void) | | 694 | process_lbrace(void) |
686 | { | | 695 | { |
687 | if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { | | 696 | if (ps.prev_lsym == lsym_rparen && ps.prev_paren_was_cast) { |
688 | ps.in_var_decl = true; // XXX: not really | | 697 | ps.in_var_decl = true; // XXX: not really |
689 | ps.in_init = true; | | 698 | ps.in_init = true; |
690 | } | | 699 | } |
691 | | | 700 | |
692 | if (out.line_kind == lk_stmt_head) | | 701 | if (out.line_kind == lk_stmt_head) |
693 | out.line_kind = lk_other; | | 702 | out.line_kind = lk_other; |
694 | | | 703 | |
695 | ps.in_stmt_or_decl = false; /* don't indent the {} */ | | 704 | ps.in_stmt_or_decl = false; /* don't indent the {} */ |
696 | | | 705 | |
697 | if (ps.in_init) | | 706 | if (ps.in_init) |
698 | ps.init_level++; | | 707 | ps.init_level++; |
699 | else | | 708 | else |
700 | ps.want_newline = true; | | 709 | ps.want_newline = true; |
701 | | | 710 | |
702 | if (code.len > 0 && !ps.in_init) { | | 711 | if (code.len > 0 && !ps.in_init) { |
703 | if (!opt.brace_same_line || | | 712 | if (!opt.brace_same_line || |
704 | (code.len > 0 && code.s[code.len - 1] == '}')) | | 713 | (code.len > 0 && code.s[code.len - 1] == '}')) |
705 | output_line(); | | 714 | output_line(); |
706 | else if (ps.in_func_def_params && !ps.in_var_decl) { | | 715 | else if (ps.in_func_def_params && !ps.in_var_decl) { |
707 | ps.ind_level_follow = 0; | | 716 | ps.ind_level_follow = 0; |
708 | if (opt.function_brace_split) | | 717 | if (opt.function_brace_split) |
709 | output_line(); | | 718 | output_line(); |
710 | else | | 719 | else |
711 | ps.want_blank = true; | | 720 | ps.want_blank = true; |
712 | } | | 721 | } |
713 | } | | 722 | } |
714 | | | 723 | |
715 | if (ps.paren.len > 0 && ps.init_level == 0) { | | 724 | if (ps.paren.len > 0 && ps.init_level == 0) { |
716 | diag(1, "Unbalanced parentheses"); | | 725 | diag(1, "Unbalanced parentheses"); |
717 | ps.paren.len = 0; | | 726 | ps.paren.len = 0; |
718 | if (ps.spaced_expr_psym != psym_0) { | | 727 | if (ps.spaced_expr_psym != psym_0) { |
719 | parse(ps.spaced_expr_psym); | | 728 | parse(ps.spaced_expr_psym); |
720 | ps.spaced_expr_psym = psym_0; | | 729 | ps.spaced_expr_psym = psym_0; |
721 | ps.ind_level = ps.ind_level_follow; | | 730 | ps.ind_level = ps.ind_level_follow; |
722 | } | | 731 | } |
723 | } | | 732 | } |
724 | | | 733 | |
725 | if (code.len == 0) | | 734 | if (code.len == 0) |
726 | ps.line_is_stmt_cont = false; | | 735 | ps.line_is_stmt_cont = false; |
727 | if (ps.in_decl && ps.in_var_decl) { | | 736 | if (ps.in_decl && ps.in_var_decl) { |
728 | ps.di_stack[ps.decl_level] = ps.decl_ind; | | 737 | ps.di_stack[ps.decl_level] = ps.decl_ind; |
729 | if (++ps.decl_level == (int)array_length(ps.di_stack)) { | | 738 | if (++ps.decl_level == (int)array_length(ps.di_stack)) { |
730 | diag(0, "Reached internal limit of %zu struct levels", | | 739 | diag(0, "Reached internal limit of %zu struct levels", |
731 | array_length(ps.di_stack)); | | 740 | array_length(ps.di_stack)); |
732 | ps.decl_level--; | | 741 | ps.decl_level--; |
733 | } | | 742 | } |
734 | } else { | | 743 | } else { |
735 | ps.line_has_decl = false; /* don't do special indentation | | 744 | ps.line_has_decl = false; /* don't do special indentation |
736 | * of comments */ | | 745 | * of comments */ |
737 | ps.in_func_def_params = false; | | 746 | ps.in_func_def_params = false; |
738 | ps.in_decl = false; | | 747 | ps.in_decl = false; |
739 | } | | 748 | } |
740 | | | 749 | |
741 | ps.decl_ind = 0; | | 750 | ps.decl_ind = 0; |
742 | parse(ps.lbrace_kind); | | 751 | parse(ps.lbrace_kind); |
743 | if (ps.want_blank) | | 752 | if (ps.want_blank) |
744 | buf_add_char(&code, ' '); | | 753 | buf_add_char(&code, ' '); |
745 | ps.want_blank = false; | | 754 | ps.want_blank = false; |
746 | buf_add_char(&code, '{'); | | 755 | buf_add_char(&code, '{'); |
747 | ps.declaration = decl_no; | | 756 | ps.declaration = decl_no; |
748 | } | | 757 | } |
749 | | | 758 | |
750 | static void | | 759 | static void |
751 | process_rbrace(void) | | 760 | process_rbrace(void) |
752 | { | | 761 | { |
753 | if (ps.paren.len > 0 && ps.init_level == 0) { | | 762 | if (ps.paren.len > 0 && ps.init_level == 0) { |
754 | diag(1, "Unbalanced parentheses"); | | 763 | diag(1, "Unbalanced parentheses"); |
755 | ps.paren.len = 0; | | 764 | ps.paren.len = 0; |
756 | ps.spaced_expr_psym = psym_0; | | 765 | ps.spaced_expr_psym = psym_0; |
757 | } | | 766 | } |
758 | | | 767 | |
759 | ps.declaration = decl_no; | | 768 | ps.declaration = decl_no; |
760 | if (ps.init_level > 0) | | 769 | if (ps.init_level > 0) |
761 | ps.init_level--; | | 770 | ps.init_level--; |
762 | | | 771 | |
763 | if (code.len > 0 && !ps.in_init) | | 772 | if (code.len > 0 && !ps.in_init) |
764 | output_line(); | | 773 | output_line(); |
765 | | | 774 | |
766 | buf_add_char(&code, '}'); | | 775 | buf_add_char(&code, '}'); |
767 | ps.want_blank = true; | | 776 | ps.want_blank = true; |
768 | ps.in_stmt_or_decl = false; // XXX: Initializers don't end a stmt | | 777 | ps.in_stmt_or_decl = false; // XXX: Initializers don't end a stmt |
769 | ps.line_is_stmt_cont = false; | | 778 | ps.line_is_stmt_cont = false; |
770 | | | 779 | |
771 | if (ps.decl_level > 0) { /* multi-level structure declaration */ | | 780 | if (ps.decl_level > 0) { /* multi-level structure declaration */ |
772 | ps.decl_ind = ps.di_stack[--ps.decl_level]; | | 781 | ps.decl_ind = ps.di_stack[--ps.decl_level]; |
773 | if (ps.decl_level == 0 && !ps.in_func_def_params) { | | 782 | if (ps.decl_level == 0 && !ps.in_func_def_params) { |
774 | ps.declaration = decl_begin; | | 783 | ps.declaration = decl_begin; |
775 | ps.decl_ind = ps.ind_level == 0 | | 784 | ps.decl_ind = ps.ind_level == 0 |
776 | ? opt.decl_indent : opt.local_decl_indent; | | 785 | ? opt.decl_indent : opt.local_decl_indent; |
777 | } | | 786 | } |
778 | ps.in_decl = true; | | 787 | ps.in_decl = true; |
779 | } | | 788 | } |
780 | | | 789 | |
781 | if (ps.psyms.len == 3) | | 790 | if (ps.psyms.len == 3) |
782 | out.line_kind = lk_func_end; | | 791 | out.line_kind = lk_func_end; |
783 | | | 792 | |
784 | parse(psym_rbrace); | | 793 | parse(psym_rbrace); |
785 | | | 794 | |
786 | if (!ps.in_var_decl | | 795 | if (!ps.in_var_decl |
787 | && ps.psyms.sym[ps.psyms.len - 1] != psym_do_stmt | | 796 | && ps.psyms.sym[ps.psyms.len - 1] != psym_do_stmt |
788 | && ps.psyms.sym[ps.psyms.len - 1] != psym_if_expr_stmt) | | 797 | && ps.psyms.sym[ps.psyms.len - 1] != psym_if_expr_stmt) |
789 | ps.want_newline = true; | | 798 | ps.want_newline = true; |
790 | } | | 799 | } |
791 | | | 800 | |
792 | static void | | 801 | static void |
793 | process_period(void) | | 802 | process_period(void) |
794 | { | | 803 | { |
795 | if (code.len > 0 && code.s[code.len - 1] == ',') | | 804 | if (code.len > 0 && code.s[code.len - 1] == ',') |
796 | buf_add_char(&code, ' '); | | 805 | buf_add_char(&code, ' '); |
797 | buf_add_char(&code, '.'); | | 806 | buf_add_char(&code, '.'); |
798 | ps.want_blank = false; | | 807 | ps.want_blank = false; |
799 | } | | 808 | } |
800 | | | 809 | |
801 | static void | | 810 | static void |
802 | process_unary_op(void) | | 811 | process_unary_op(void) |
803 | { | | 812 | { |
804 | if (is_function_pointer_declaration()) { | | 813 | if (is_function_pointer_declaration()) { |
805 | int ind = ps.decl_ind - (int)token.len; | | 814 | int ind = ps.decl_ind - (int)token.len; |
806 | indent_declarator(ind, ps.tabs_to_var); | | 815 | indent_declarator(ind, ps.tabs_to_var); |
807 | } else if ((token.s[0] == '+' || token.s[0] == '-') | | 816 | } else if ((token.s[0] == '+' || token.s[0] == '-') |
808 | && code.len > 0 && code.s[code.len - 1] == token.s[0]) | | 817 | && code.len > 0 && code.s[code.len - 1] == token.s[0]) |
809 | ps.want_blank = true; | | 818 | ps.want_blank = true; |
810 | | | 819 | |
811 | if (ps.want_blank) | | 820 | if (ps.want_blank) |
812 | buf_add_char(&code, ' '); | | 821 | buf_add_char(&code, ' '); |
813 | buf_add_buf(&code, &token); | | 822 | buf_add_buf(&code, &token); |
814 | ps.want_blank = false; | | 823 | ps.want_blank = false; |
815 | } | | 824 | } |
816 | | | 825 | |
817 | static void | | 826 | static void |
818 | process_postfix_op(void) | | 827 | process_postfix_op(void) |
819 | { | | 828 | { |
820 | buf_add_buf(&code, &token); | | 829 | buf_add_buf(&code, &token); |
821 | ps.want_blank = true; | | 830 | ps.want_blank = true; |
822 | } | | 831 | } |
823 | | | 832 | |
824 | static void | | 833 | static void |
825 | process_comma(void) | | 834 | process_comma(void) |
826 | { | | 835 | { |
827 | ps.want_blank = code.len > 0; /* only put blank after comma if comma | | 836 | ps.want_blank = code.len > 0; /* only put blank after comma if comma |
828 | * does not start the line */ | | 837 | * does not start the line */ |
829 | | | 838 | |
830 | if (ps.in_decl && ps.ind_paren_level == 0 | | 839 | if (ps.in_decl && ps.ind_paren_level == 0 |
831 | && !ps.line_has_func_def && !ps.in_init && !ps.decl_indent_done) { | | 840 | && !ps.line_has_func_def && !ps.in_init && !ps.decl_indent_done) { |
832 | /* indent leading commas and not the actual identifiers */ | | 841 | /* indent leading commas and not the actual identifiers */ |
833 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | | 842 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); |
834 | } | | 843 | } |
835 | | | 844 | |
836 | buf_add_char(&code, ','); | | 845 | buf_add_char(&code, ','); |
837 | | | 846 | |
838 | if (ps.paren.len == 0) { | | 847 | if (ps.paren.len == 0) { |
839 | if (ps.init_level == 0) | | 848 | if (ps.init_level == 0) |
840 | ps.in_init = false; | | 849 | ps.in_init = false; |
841 | int typical_varname_length = 8; | | 850 | int typical_varname_length = 8; |
842 | if (ps.break_after_comma && (opt.break_after_comma || | | 851 | if (ps.break_after_comma && (opt.break_after_comma || |
843 | ind_add(compute_code_indent(), code.s, code.len) | | 852 | ind_add(compute_code_indent(), code.s, code.len) |
844 | >= opt.max_line_length - typical_varname_length)) | | 853 | >= opt.max_line_length - typical_varname_length)) |
845 | ps.want_newline = true; | | 854 | ps.want_newline = true; |
846 | } | | 855 | } |
847 | } | | 856 | } |
848 | | | 857 | |
849 | static void | | 858 | static void |
850 | process_label_colon(void) | | 859 | process_label_colon(void) |
851 | { | | 860 | { |
852 | buf_add_buf(&lab, &code); | | 861 | buf_add_buf(&lab, &code); |
853 | buf_add_char(&lab, ':'); | | 862 | buf_add_char(&lab, ':'); |
854 | buf_clear(&code); | | 863 | buf_clear(&code); |
855 | | | 864 | |
856 | if (ps.seen_case) | | 865 | if (ps.seen_case) |
857 | out.line_kind = lk_case_or_default; | | 866 | out.line_kind = lk_case_or_default; |
858 | ps.in_stmt_or_decl = false; | | 867 | ps.in_stmt_or_decl = false; |
859 | ps.want_newline = ps.seen_case; | | 868 | ps.want_newline = ps.seen_case; |
860 | ps.seen_case = false; | | 869 | ps.seen_case = false; |
861 | ps.want_blank = false; | | 870 | ps.want_blank = false; |
862 | } | | 871 | } |
863 | | | 872 | |
864 | static void | | 873 | static void |
865 | process_other_colon(void) | | 874 | process_other_colon(void) |
866 | { | | 875 | { |
867 | buf_add_char(&code, ':'); | | 876 | buf_add_char(&code, ':'); |
868 | ps.want_blank = ps.decl_level == 0; | | 877 | ps.want_blank = ps.decl_level == 0; |
869 | } | | 878 | } |
870 | | | 879 | |
871 | static void | | 880 | static void |
872 | process_semicolon(void) | | 881 | process_semicolon(void) |
873 | { | | 882 | { |
874 | if (out.line_kind == lk_stmt_head) | | 883 | if (out.line_kind == lk_stmt_head) |
875 | out.line_kind = lk_other; | | 884 | out.line_kind = lk_other; |
876 | if (ps.decl_level == 0) { | | 885 | if (ps.decl_level == 0) { |
877 | ps.in_var_decl = false; | | 886 | ps.in_var_decl = false; |
878 | ps.in_typedef_decl = false; | | 887 | ps.in_typedef_decl = false; |
879 | } | | 888 | } |
880 | ps.seen_case = false; /* only needs to be reset on error */ | | 889 | ps.seen_case = false; /* only needs to be reset on error */ |
881 | ps.quest_level = 0; /* only needs to be reset on error */ | | 890 | ps.quest_level = 0; /* only needs to be reset on error */ |
882 | if (ps.prev_lsym == lsym_rparen) | | 891 | if (ps.prev_lsym == lsym_rparen) |
883 | ps.in_func_def_params = false; | | 892 | ps.in_func_def_params = false; |
884 | ps.in_init = false; | | 893 | ps.in_init = false; |
885 | ps.init_level = 0; | | 894 | ps.init_level = 0; |
886 | ps.declaration = ps.declaration == decl_begin ? decl_end : decl_no; | | 895 | ps.declaration = ps.declaration == decl_begin ? decl_end : decl_no; |
887 | | | 896 | |
888 | if (ps.in_decl && code.len == 0 && !ps.in_init && | | 897 | if (ps.in_decl && code.len == 0 && !ps.in_init && |
889 | !ps.decl_indent_done && ps.ind_paren_level == 0) { | | 898 | !ps.decl_indent_done && ps.ind_paren_level == 0) { |
890 | /* indent stray semicolons in declarations */ | | 899 | /* indent stray semicolons in declarations */ |
891 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); | | 900 | indent_declarator(ps.decl_ind - 1, ps.tabs_to_var); |
892 | } | | 901 | } |
893 | | | 902 | |
894 | ps.in_decl = ps.decl_level > 0; /* if we were in a first level | | 903 | ps.in_decl = ps.decl_level > 0; /* if we were in a first level |
895 | * structure declaration before, we | | 904 | * structure declaration before, we |
896 | * aren't anymore */ | | 905 | * aren't anymore */ |
897 | | | 906 | |
898 | if (ps.paren.len > 0 && ps.spaced_expr_psym != psym_for_exprs) { | | 907 | if (ps.paren.len > 0 && ps.spaced_expr_psym != psym_for_exprs) { |
899 | diag(1, "Unbalanced parentheses"); | | 908 | diag(1, "Unbalanced parentheses"); |
900 | ps.paren.len = 0; | | 909 | ps.paren.len = 0; |
901 | if (ps.spaced_expr_psym != psym_0) { | | 910 | if (ps.spaced_expr_psym != psym_0) { |
902 | parse(ps.spaced_expr_psym); | | 911 | parse(ps.spaced_expr_psym); |
903 | ps.spaced_expr_psym = psym_0; | | 912 | ps.spaced_expr_psym = psym_0; |
904 | } | | 913 | } |
905 | } | | 914 | } |
906 | buf_add_char(&code, ';'); | | 915 | buf_add_char(&code, ';'); |
907 | ps.want_blank = true; | | 916 | ps.want_blank = true; |
908 | ps.in_stmt_or_decl = ps.paren.len > 0; | | 917 | ps.in_stmt_or_decl = ps.paren.len > 0; |
909 | ps.decl_ind = 0; | | 918 | ps.decl_ind = 0; |
910 | | | 919 | |
911 | if (ps.spaced_expr_psym == psym_0) { | | 920 | if (ps.spaced_expr_psym == psym_0) { |
912 | parse(psym_stmt); | | 921 | parse(psym_stmt); |
913 | ps.want_newline = true; | | 922 | ps.want_newline = true; |
914 | } | | 923 | } |
915 | } | | 924 | } |
916 | | | 925 | |
917 | static void | | 926 | static void |
918 | process_type_outside_parentheses(void) | | 927 | process_type_outside_parentheses(void) |
919 | { | | 928 | { |
920 | parse(psym_decl); /* let the parser worry about indentation */ | | 929 | parse(psym_decl); /* let the parser worry about indentation */ |
921 | | | 930 | |
922 | if (ps.prev_lsym == lsym_rparen && ps.psyms.len <= 2 && code.len > 0) | | 931 | if (ps.prev_lsym == lsym_rparen && ps.psyms.len <= 2 && code.len > 0) |
923 | output_line(); | | 932 | output_line(); |
924 | | | 933 | |
925 | if (ps.in_func_def_params && opt.indent_parameters && | | 934 | if (ps.in_func_def_params && opt.indent_parameters && |
926 | ps.decl_level == 0) { | | 935 | ps.decl_level == 0) { |
927 | ps.ind_level = ps.ind_level_follow = 1; | | 936 | ps.ind_level = ps.ind_level_follow = 1; |
928 | ps.line_is_stmt_cont = false; | | 937 | ps.line_is_stmt_cont = false; |
929 | } | | 938 | } |
930 | | | 939 | |
931 | ps.in_var_decl = /* maybe */ true; | | 940 | ps.in_var_decl = /* maybe */ true; |
932 | ps.in_decl = true; | | 941 | ps.in_decl = true; |
933 | ps.line_has_decl = ps.in_decl; | | 942 | ps.line_has_decl = ps.in_decl; |
934 | if (ps.decl_level == 0) | | 943 | if (ps.decl_level == 0) |
935 | ps.declaration = decl_begin; | | 944 | ps.declaration = decl_begin; |
936 | | | 945 | |
937 | int ind = ps.ind_level > 0 && ps.decl_level == 0 | | 946 | int ind = ps.ind_level > 0 && ps.decl_level == 0 |
938 | ? opt.local_decl_indent /* local variable */ | | 947 | ? opt.local_decl_indent /* local variable */ |
939 | : opt.decl_indent; /* global variable, or member */ | | 948 | : opt.decl_indent; /* global variable, or member */ |
940 | if (ind == 0) { | | 949 | if (ind == 0) { |
941 | int ind0 = code.len > 0 ? ind_add(0, code.s, code.len) + 1 : 0; | | 950 | int ind0 = code.len > 0 ? ind_add(0, code.s, code.len) + 1 : 0; |
942 | ps.decl_ind = ind_add(ind0, token.s, token.len) + 1; | | 951 | ps.decl_ind = ind_add(ind0, token.s, token.len) + 1; |
943 | } else | | 952 | } else |
944 | ps.decl_ind = ind; | | 953 | ps.decl_ind = ind; |
945 | ps.tabs_to_var = opt.use_tabs && ind > 0; | | 954 | ps.tabs_to_var = opt.use_tabs && ind > 0; |
946 | } | | 955 | } |
947 | | | 956 | |
948 | static void | | 957 | static void |
949 | process_word(lexer_symbol lsym) | | 958 | process_word(lexer_symbol lsym) |
950 | { | | 959 | { |
951 | if (ps.in_decl) { | | 960 | if (ps.in_decl) { |
952 | if (lsym == lsym_funcname) { | | 961 | if (lsym == lsym_funcname) { |
953 | ps.in_decl = false; | | 962 | ps.in_decl = false; |
954 | if (opt.procnames_start_line && code.len > 0) | | 963 | if (opt.procnames_start_line && code.len > 0) |
955 | output_line(); | | 964 | output_line(); |
956 | else if (ps.want_blank) | | 965 | else if (ps.want_blank) |
957 | buf_add_char(&code, ' '); | | 966 | buf_add_char(&code, ' '); |
958 | ps.want_blank = false; | | 967 | ps.want_blank = false; |
959 | } else if (ps.in_typedef_decl && ps.decl_level == 0) { | | 968 | } else if (ps.in_typedef_decl && ps.decl_level == 0) { |
960 | /* Do not indent typedef declarators. */ | | 969 | /* Do not indent typedef declarators. */ |
961 | } else if (!ps.in_init && !ps.decl_indent_done && | | 970 | } else if (!ps.in_init && !ps.decl_indent_done && |
962 | ps.ind_paren_level == 0) { | | 971 | ps.ind_paren_level == 0) { |
963 | if (opt.decl_indent == 0 | | 972 | if (opt.decl_indent == 0 |
964 | && code.len > 0 && code.s[code.len - 1] == '}') | | 973 | && code.len > 0 && code.s[code.len - 1] == '}') |
965 | ps.decl_ind = ind_add(0, code.s, code.len) + 1; | | 974 | ps.decl_ind = ind_add(0, code.s, code.len) + 1; |
966 | indent_declarator(ps.decl_ind, ps.tabs_to_var); | | 975 | indent_declarator(ps.decl_ind, ps.tabs_to_var); |
967 | } | | 976 | } |
968 | | | 977 | |
969 | } else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { | | 978 | } else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) { |
970 | parse(ps.spaced_expr_psym); | | 979 | parse(ps.spaced_expr_psym); |
971 | ps.spaced_expr_psym = psym_0; | | 980 | ps.spaced_expr_psym = psym_0; |
972 | ps.want_newline = true; | | 981 | ps.want_newline = true; |
973 | ps.in_stmt_or_decl = false; | | 982 | ps.in_stmt_or_decl = false; |
974 | ps.next_unary = true; | | 983 | ps.next_unary = true; |
975 | } | | 984 | } |
976 | } | | 985 | } |
977 | | | 986 | |
978 | static void | | 987 | static void |
979 | process_do(void) | | 988 | process_do(void) |
980 | { | | 989 | { |
981 | ps.in_stmt_or_decl = false; | | 990 | ps.in_stmt_or_decl = false; |
982 | ps.in_decl = false; | | 991 | ps.in_decl = false; |
983 | | | 992 | |
984 | if (code.len > 0) | | 993 | if (code.len > 0) |
985 | output_line(); | | 994 | output_line(); |
986 | | | 995 | |
987 | parse(psym_do); | | 996 | parse(psym_do); |
988 | ps.want_newline = true; | | 997 | ps.want_newline = true; |
989 | } | | 998 | } |
990 | | | 999 | |
991 | static void | | 1000 | static void |
992 | process_else(void) | | 1001 | process_else(void) |
993 | { | | 1002 | { |
994 | ps.in_stmt_or_decl = false; | | 1003 | ps.in_stmt_or_decl = false; |
995 | ps.in_decl = false; | | 1004 | ps.in_decl = false; |
996 | | | 1005 | |
997 | if (code.len > 0 | | 1006 | if (code.len > 0 |
998 | && !(opt.cuddle_else && code.s[code.len - 1] == '}')) | | 1007 | && !(opt.cuddle_else && code.s[code.len - 1] == '}')) |
999 | output_line(); | | 1008 | output_line(); |
1000 | | | 1009 | |
1001 | parse(psym_else); | | 1010 | parse(psym_else); |
1002 | ps.want_newline = true; | | 1011 | ps.want_newline = true; |
1003 | } | | 1012 | } |
1004 | | | 1013 | |
1005 | static void | | 1014 | static void |
1006 | process_lsym(lexer_symbol lsym) | | 1015 | process_lsym(lexer_symbol lsym) |
1007 | { | | 1016 | { |
1008 | switch (lsym) { | | 1017 | switch (lsym) { |
1009 | /* INDENT OFF */ | | 1018 | /* INDENT OFF */ |
1010 | case lsym_preprocessing: process_preprocessing(); break; | | 1019 | case lsym_preprocessing: process_preprocessing(); break; |
1011 | case lsym_newline: process_newline(); break; | | 1020 | case lsym_newline: process_newline(); break; |
1012 | case lsym_comment: process_comment(); break; | | 1021 | case lsym_comment: process_comment(); break; |
1013 | case lsym_lparen: process_lparen(); break; | | 1022 | case lsym_lparen: process_lparen(); break; |
1014 | case lsym_lbracket: process_lbracket(); break; | | 1023 | case lsym_lbracket: process_lbracket(); break; |
1015 | case lsym_rparen: process_rparen(); break; | | 1024 | case lsym_rparen: process_rparen(); break; |
1016 | case lsym_rbracket: process_rbracket(); break; | | 1025 | case lsym_rbracket: process_rbracket(); break; |
1017 | case lsym_lbrace: process_lbrace(); break; | | 1026 | case lsym_lbrace: process_lbrace(); break; |
1018 | case lsym_rbrace: process_rbrace(); break; | | 1027 | case lsym_rbrace: process_rbrace(); break; |
1019 | case lsym_period: process_period(); break; | | 1028 | case lsym_period: process_period(); break; |
1020 | case lsym_unary_op: process_unary_op(); break; | | 1029 | case lsym_unary_op: process_unary_op(); break; |
1021 | case lsym_postfix_op: process_postfix_op(); break; | | 1030 | case lsym_postfix_op: process_postfix_op(); break; |
1022 | case lsym_binary_op: goto copy_token; | | 1031 | case lsym_binary_op: goto copy_token; |
1023 | case lsym_question: ps.quest_level++; goto copy_token; | | 1032 | case lsym_question: ps.quest_level++; goto copy_token; |
1024 | case lsym_question_colon: goto copy_token; | | 1033 | case lsym_question_colon: goto copy_token; |
1025 | case lsym_label_colon: process_label_colon(); break; | | 1034 | case lsym_label_colon: process_label_colon(); break; |
1026 | case lsym_other_colon: process_other_colon(); break; | | 1035 | case lsym_other_colon: process_other_colon(); break; |
1027 | case lsym_comma: process_comma(); break; | | 1036 | case lsym_comma: process_comma(); break; |
1028 | case lsym_semicolon: process_semicolon(); break; | | 1037 | case lsym_semicolon: process_semicolon(); break; |
1029 | case lsym_typedef: ps.in_typedef_decl = true; goto copy_token; | | 1038 | case lsym_typedef: ps.in_typedef_decl = true; goto copy_token; |
1030 | case lsym_modifier: goto copy_token; | | 1039 | case lsym_modifier: goto copy_token; |
1031 | case lsym_case: ps.seen_case = true; goto copy_token; | | 1040 | case lsym_case: ps.seen_case = true; goto copy_token; |
1032 | case lsym_default: ps.seen_case = true; goto copy_token; | | 1041 | case lsym_default: ps.seen_case = true; goto copy_token; |
1033 | case lsym_do: process_do(); goto copy_token; | | 1042 | case lsym_do: process_do(); goto copy_token; |
1034 | case lsym_else: process_else(); goto copy_token; | | 1043 | case lsym_else: process_else(); goto copy_token; |
1035 | case lsym_for: ps.spaced_expr_psym = psym_for_exprs; goto copy_token; | | 1044 | case lsym_for: ps.spaced_expr_psym = psym_for_exprs; goto copy_token; |
1036 | case lsym_if: ps.spaced_expr_psym = psym_if_expr; goto copy_token; | | 1045 | case lsym_if: ps.spaced_expr_psym = psym_if_expr; goto copy_token; |
1037 | case lsym_switch: ps.spaced_expr_psym = psym_switch_expr; goto copy_token; | | 1046 | case lsym_switch: ps.spaced_expr_psym = psym_switch_expr; goto copy_token; |
1038 | case lsym_while: ps.spaced_expr_psym = psym_while_expr; goto copy_token; | | 1047 | case lsym_while: ps.spaced_expr_psym = psym_while_expr; goto copy_token; |
1039 | /* INDENT ON */ | | 1048 | /* INDENT ON */ |
1040 | | | 1049 | |
1041 | case lsym_tag: | | 1050 | case lsym_tag: |
1042 | if (ps.paren.len > 0) | | 1051 | if (ps.paren.len > 0) |
1043 | goto copy_token; | | 1052 | goto copy_token; |
1044 | /* FALLTHROUGH */ | | 1053 | /* FALLTHROUGH */ |
1045 | case lsym_type_outside_parentheses: | | 1054 | case lsym_type_outside_parentheses: |
1046 | process_type_outside_parentheses(); | | 1055 | process_type_outside_parentheses(); |
1047 | goto copy_token; | | 1056 | goto copy_token; |
1048 | | | 1057 | |
1049 | case lsym_type_in_parentheses: | | 1058 | case lsym_type_in_parentheses: |
1050 | case lsym_sizeof: | | 1059 | case lsym_sizeof: |
1051 | case lsym_offsetof: | | 1060 | case lsym_offsetof: |
1052 | case lsym_word: | | 1061 | case lsym_word: |
1053 | case lsym_funcname: | | 1062 | case lsym_funcname: |
1054 | case lsym_return: | | 1063 | case lsym_return: |
1055 | process_word(lsym); | | 1064 | process_word(lsym); |
1056 | copy_token: | | 1065 | copy_token: |
1057 | if (ps.want_blank) | | 1066 | if (ps.want_blank) |
1058 | buf_add_char(&code, ' '); | | 1067 | buf_add_char(&code, ' '); |
1059 | buf_add_buf(&code, &token); | | 1068 | buf_add_buf(&code, &token); |
1060 | if (lsym != lsym_funcname) | | 1069 | if (lsym != lsym_funcname) |
1061 | ps.want_blank = true; | | 1070 | ps.want_blank = true; |
1062 | break; | | 1071 | break; |
1063 | | | 1072 | |
1064 | default: | | 1073 | default: |
1065 | break; | | 1074 | break; |
1066 | } | | 1075 | } |
1067 | } | | 1076 | } |
1068 | | | 1077 | |
1069 | static int | | 1078 | static int |
1070 | indent(void) | | 1079 | indent(void) |
1071 | { | | 1080 | { |
1072 | debug_parser_state(); | | 1081 | debug_parser_state(); |
1073 | | | 1082 | |
1074 | for (;;) { /* loop until we reach eof */ | | 1083 | for (;;) { /* loop until we reach eof */ |
1075 | lexer_symbol lsym = lexi(); | | 1084 | lexer_symbol lsym = lexi(); |
1076 | | | 1085 | |
1077 | debug_blank_line(); | | 1086 | debug_blank_line(); |
1078 | debug_printf("line %d: %s", line_no, lsym_name[lsym]); | | 1087 | debug_printf("line %d: %s", line_no, lsym_name[lsym]); |
1079 | debug_print_buf("token", &token); | | 1088 | debug_print_buf("token", &token); |
1080 | debug_buffers(); | | 1089 | debug_buffers(); |
1081 | debug_blank_line(); | | 1090 | debug_blank_line(); |
1082 | | | 1091 | |
1083 | if (lsym == lsym_eof) | | 1092 | if (lsym == lsym_eof) |
1084 | return process_eof(); | | 1093 | return process_eof(); |
1085 | | | 1094 | |
1086 | if (lsym == lsym_preprocessing || lsym == lsym_newline) | | 1095 | if (lsym == lsym_preprocessing || lsym == lsym_newline) |
1087 | ps.want_newline = false; | | 1096 | ps.want_newline = false; |
1088 | else if (lsym == lsym_comment) { | | 1097 | else if (lsym == lsym_comment) { |
1089 | /* no special processing */ | | 1098 | /* no special processing */ |
1090 | } else { | | 1099 | } else { |
1091 | if (lsym == lsym_if && ps.prev_lsym == lsym_else | | 1100 | if (lsym == lsym_if && ps.prev_lsym == lsym_else |
1092 | && opt.else_if_in_same_line) | | 1101 | && opt.else_if_in_same_line) |
1093 | ps.want_newline = false; | | 1102 | ps.want_newline = false; |
1094 | | | 1103 | |
1095 | if (ps.want_newline && should_break_line(lsym)) { | | 1104 | if (ps.want_newline && should_break_line(lsym)) { |
1096 | ps.want_newline = false; | | 1105 | ps.want_newline = false; |
1097 | output_line(); | | 1106 | output_line(); |
1098 | } | | 1107 | } |
1099 | ps.in_stmt_or_decl = true; | | 1108 | ps.in_stmt_or_decl = true; |
1100 | if (com.len > 0) | | 1109 | if (com.len > 0) |
1101 | move_com_to_code(lsym); | | 1110 | move_com_to_code(lsym); |
1102 | update_ps_lbrace_kind(lsym); | | 1111 | update_ps_lbrace_kind(lsym); |
1103 | } | | 1112 | } |
1104 | | | 1113 | |
1105 | process_lsym(lsym); | | 1114 | process_lsym(lsym); |
1106 | | | 1115 | |
1107 | if (lsym != lsym_preprocessing | | 1116 | if (lsym != lsym_preprocessing |
1108 | && lsym != lsym_newline | | 1117 | && lsym != lsym_newline |
1109 | && lsym != lsym_comment) | | 1118 | && lsym != lsym_comment) |
1110 | ps.prev_lsym = lsym; | | 1119 | ps.prev_lsym = lsym; |
1111 | | | 1120 | |
1112 | debug_parser_state(); | | 1121 | debug_parser_state(); |
1113 | } | | 1122 | } |
1114 | } | | 1123 | } |
1115 | | | 1124 | |
1116 | int | | 1125 | int |
1117 | main(int argc, char **argv) | | 1126 | main(int argc, char **argv) |
1118 | { | | 1127 | { |
1119 | init_globals(); | | 1128 | init_globals(); |
1120 | load_profiles(argc, argv); | | 1129 | load_profiles(argc, argv); |
1121 | parse_command_line(argc, argv); | | 1130 | parse_command_line(argc, argv); |
1122 | set_initial_indentation(); | | 1131 | set_initial_indentation(); |
1123 | return indent(); | | 1132 | return indent(); |
1124 | } | | 1133 | } |