indent: use consistent indentation for 'else' Half of the code used -ce, the other half the opposite -nce. No functional change.diff -r1.18 -r1.19 src/usr.bin/indent/args.c
(rillig)
--- src/usr.bin/indent/args.c 2021/03/09 16:48:28 1.18
+++ src/usr.bin/indent/args.c 2021/03/12 23:10:18 1.19
@@ -1,360 +1,359 @@ | @@ -1,360 +1,359 @@ | |||
1 | /* $NetBSD: args.c,v 1.18 2021/03/09 16:48:28 rillig Exp $ */ | 1 | /* $NetBSD: args.c,v 1.19 2021/03/12 23:10:18 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1980, 1993 | 7 | * Copyright (c) 1980, 1993 | |
8 | * The Regents of the University of California. All rights reserved. | 8 | * The Regents of the University of California. All rights reserved. | |
9 | * All rights reserved. | 9 | * All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #if 0 | 40 | #if 0 | |
41 | #ifndef lint | 41 | #ifndef lint | |
42 | static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; | 42 | static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; | |
43 | #endif /* not lint */ | 43 | #endif /* not lint */ | |
44 | #endif | 44 | #endif | |
45 | 45 | |||
46 | #include <sys/cdefs.h> | 46 | #include <sys/cdefs.h> | |
47 | #ifndef lint | 47 | #ifndef lint | |
48 | #if defined(__NetBSD__) | 48 | #if defined(__NetBSD__) | |
49 | __RCSID("$NetBSD: args.c,v 1.18 2021/03/09 16:48:28 rillig Exp $"); | 49 | __RCSID("$NetBSD: args.c,v 1.19 2021/03/12 23:10:18 rillig Exp $"); | |
50 | #elif defined(__FreeBSD__) | 50 | #elif defined(__FreeBSD__) | |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/args.c 336318 2018-07-15 21:04:21Z pstef $"); | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/args.c 336318 2018-07-15 21:04:21Z pstef $"); | |
52 | #endif | 52 | #endif | |
53 | #endif | 53 | #endif | |
54 | 54 | |||
55 | /* | 55 | /* | |
56 | * Argument scanning and profile reading code. Default parameters are set | 56 | * Argument scanning and profile reading code. Default parameters are set | |
57 | * here as well. | 57 | * here as well. | |
58 | */ | 58 | */ | |
59 | 59 | |||
60 | #include <ctype.h> | 60 | #include <ctype.h> | |
61 | #include <err.h> | 61 | #include <err.h> | |
62 | #include <limits.h> | 62 | #include <limits.h> | |
63 | #include <stdio.h> | 63 | #include <stdio.h> | |
64 | #include <stdlib.h> | 64 | #include <stdlib.h> | |
65 | #include <string.h> | 65 | #include <string.h> | |
66 | 66 | |||
67 | #include "indent.h" | 67 | #include "indent.h" | |
68 | 68 | |||
69 | #define INDENT_VERSION "2.0" | 69 | #define INDENT_VERSION "2.0" | |
70 | 70 | |||
71 | /* profile types */ | 71 | /* profile types */ | |
72 | #define PRO_SPECIAL 1 /* special case */ | 72 | #define PRO_SPECIAL 1 /* special case */ | |
73 | #define PRO_BOOL 2 /* boolean */ | 73 | #define PRO_BOOL 2 /* boolean */ | |
74 | #define PRO_INT 3 /* integer */ | 74 | #define PRO_INT 3 /* integer */ | |
75 | 75 | |||
76 | /* profile specials for booleans */ | 76 | /* profile specials for booleans */ | |
77 | #define ON 1 /* turn it on */ | 77 | #define ON 1 /* turn it on */ | |
78 | #define OFF 0 /* turn it off */ | 78 | #define OFF 0 /* turn it off */ | |
79 | 79 | |||
80 | /* profile specials for specials */ | 80 | /* profile specials for specials */ | |
81 | #define IGN 1 /* ignore it */ | 81 | #define IGN 1 /* ignore it */ | |
82 | #define CLI 2 /* case label indent (float) */ | 82 | #define CLI 2 /* case label indent (float) */ | |
83 | #define STDIN 3 /* use stdin */ | 83 | #define STDIN 3 /* use stdin */ | |
84 | #define KEY 4 /* type (keyword) */ | 84 | #define KEY 4 /* type (keyword) */ | |
85 | 85 | |||
86 | static void scan_profile(FILE *); | 86 | static void scan_profile(FILE *); | |
87 | 87 | |||
88 | #define KEY_FILE 5 /* only used for args */ | 88 | #define KEY_FILE 5 /* only used for args */ | |
89 | #define VERSION 6 /* only used for args */ | 89 | #define VERSION 6 /* only used for args */ | |
90 | 90 | |||
91 | const char *option_source = "?"; | 91 | const char *option_source = "?"; | |
92 | 92 | |||
93 | void add_typedefs_from_file(const char *str); | 93 | void add_typedefs_from_file(const char *str); | |
94 | 94 | |||
95 | /* | 95 | /* | |
96 | * N.B.: because of the way the table here is scanned, options whose names are | 96 | * N.B.: because of the way the table here is scanned, options whose names are | |
97 | * substrings of other options must occur later; that is, with -lp vs -l, -lp | 97 | * substrings of other options must occur later; that is, with -lp vs -l, -lp | |
98 | * must be first. Also, while (most) booleans occur more than once, the last | 98 | * must be first. Also, while (most) booleans occur more than once, the last | |
99 | * default value is the one actually assigned. | 99 | * default value is the one actually assigned. | |
100 | */ | 100 | */ | |
101 | const struct pro { | 101 | const struct pro { | |
102 | const char *p_name; /* name, e.g. -bl, -cli */ | 102 | const char *p_name; /* name, e.g. -bl, -cli */ | |
103 | int p_type; /* type (int, bool, special) */ | 103 | int p_type; /* type (int, bool, special) */ | |
104 | int p_default; /* the default value (if int) */ | 104 | int p_default; /* the default value (if int) */ | |
105 | int p_special; /* depends on type */ | 105 | int p_special; /* depends on type */ | |
106 | int *p_obj; /* the associated variable */ | 106 | int *p_obj; /* the associated variable */ | |
107 | } pro[] = { | 107 | } pro[] = { | |
108 | {"T", PRO_SPECIAL, 0, KEY, 0}, | 108 | {"T", PRO_SPECIAL, 0, KEY, 0}, | |
109 | {"U", PRO_SPECIAL, 0, KEY_FILE, 0}, | 109 | {"U", PRO_SPECIAL, 0, KEY_FILE, 0}, | |
110 | {"-version", PRO_SPECIAL, 0, VERSION, 0}, | 110 | {"-version", PRO_SPECIAL, 0, VERSION, 0}, | |
111 | {"P", PRO_SPECIAL, 0, IGN, 0}, | 111 | {"P", PRO_SPECIAL, 0, IGN, 0}, | |
112 | {"bacc", PRO_BOOL, false, ON, &opt.blanklines_around_conditional_compilation}, | 112 | {"bacc", PRO_BOOL, false, ON, &opt.blanklines_around_conditional_compilation}, | |
113 | {"badp", PRO_BOOL, false, ON, &opt.blanklines_after_declarations_at_proctop}, | 113 | {"badp", PRO_BOOL, false, ON, &opt.blanklines_after_declarations_at_proctop}, | |
114 | {"bad", PRO_BOOL, false, ON, &opt.blanklines_after_declarations}, | 114 | {"bad", PRO_BOOL, false, ON, &opt.blanklines_after_declarations}, | |
115 | {"bap", PRO_BOOL, false, ON, &opt.blanklines_after_procs}, | 115 | {"bap", PRO_BOOL, false, ON, &opt.blanklines_after_procs}, | |
116 | {"bbb", PRO_BOOL, false, ON, &opt.blanklines_before_blockcomments}, | 116 | {"bbb", PRO_BOOL, false, ON, &opt.blanklines_before_blockcomments}, | |
117 | {"bc", PRO_BOOL, true, OFF, &opt.leave_comma}, | 117 | {"bc", PRO_BOOL, true, OFF, &opt.leave_comma}, | |
118 | {"bl", PRO_BOOL, true, OFF, &opt.btype_2}, | 118 | {"bl", PRO_BOOL, true, OFF, &opt.btype_2}, | |
119 | {"br", PRO_BOOL, true, ON, &opt.btype_2}, | 119 | {"br", PRO_BOOL, true, ON, &opt.btype_2}, | |
120 | {"bs", PRO_BOOL, false, ON, &opt.Bill_Shannon}, | 120 | {"bs", PRO_BOOL, false, ON, &opt.Bill_Shannon}, | |
121 | {"cdb", PRO_BOOL, true, ON, &opt.comment_delimiter_on_blankline}, | 121 | {"cdb", PRO_BOOL, true, ON, &opt.comment_delimiter_on_blankline}, | |
122 | {"cd", PRO_INT, 0, 0, &opt.decl_com_ind}, | 122 | {"cd", PRO_INT, 0, 0, &opt.decl_com_ind}, | |
123 | {"ce", PRO_BOOL, true, ON, &opt.cuddle_else}, | 123 | {"ce", PRO_BOOL, true, ON, &opt.cuddle_else}, | |
124 | {"ci", PRO_INT, 0, 0, &opt.continuation_indent}, | 124 | {"ci", PRO_INT, 0, 0, &opt.continuation_indent}, | |
125 | {"cli", PRO_SPECIAL, 0, CLI, 0}, | 125 | {"cli", PRO_SPECIAL, 0, CLI, 0}, | |
126 | {"cs", PRO_BOOL, false, ON, &opt.space_after_cast}, | 126 | {"cs", PRO_BOOL, false, ON, &opt.space_after_cast}, | |
127 | {"c", PRO_INT, 33, 0, &opt.com_ind}, | 127 | {"c", PRO_INT, 33, 0, &opt.com_ind}, | |
128 | {"di", PRO_INT, 16, 0, &opt.decl_indent}, | 128 | {"di", PRO_INT, 16, 0, &opt.decl_indent}, | |
129 | {"dj", PRO_BOOL, false, ON, &opt.ljust_decl}, | 129 | {"dj", PRO_BOOL, false, ON, &opt.ljust_decl}, | |
130 | {"d", PRO_INT, 0, 0, &opt.unindent_displace}, | 130 | {"d", PRO_INT, 0, 0, &opt.unindent_displace}, | |
131 | {"eei", PRO_BOOL, false, ON, &opt.extra_expression_indent}, | 131 | {"eei", PRO_BOOL, false, ON, &opt.extra_expression_indent}, | |
132 | {"ei", PRO_BOOL, true, ON, &opt.else_if}, | 132 | {"ei", PRO_BOOL, true, ON, &opt.else_if}, | |
133 | {"fbs", PRO_BOOL, true, ON, &opt.function_brace_split}, | 133 | {"fbs", PRO_BOOL, true, ON, &opt.function_brace_split}, | |
134 | {"fc1", PRO_BOOL, true, ON, &opt.format_col1_comments}, | 134 | {"fc1", PRO_BOOL, true, ON, &opt.format_col1_comments}, | |
135 | {"fcb", PRO_BOOL, true, ON, &opt.format_block_comments}, | 135 | {"fcb", PRO_BOOL, true, ON, &opt.format_block_comments}, | |
136 | {"ip", PRO_BOOL, true, ON, &opt.indent_parameters}, | 136 | {"ip", PRO_BOOL, true, ON, &opt.indent_parameters}, | |
137 | {"i", PRO_INT, 8, 0, &opt.ind_size}, | 137 | {"i", PRO_INT, 8, 0, &opt.ind_size}, | |
138 | {"lc", PRO_INT, 0, 0, &opt.block_comment_max_col}, | 138 | {"lc", PRO_INT, 0, 0, &opt.block_comment_max_col}, | |
139 | {"ldi", PRO_INT, -1, 0, &opt.local_decl_indent}, | 139 | {"ldi", PRO_INT, -1, 0, &opt.local_decl_indent}, | |
140 | {"lpl", PRO_BOOL, false, ON, &opt.lineup_to_parens_always}, | 140 | {"lpl", PRO_BOOL, false, ON, &opt.lineup_to_parens_always}, | |
141 | {"lp", PRO_BOOL, true, ON, &opt.lineup_to_parens}, | 141 | {"lp", PRO_BOOL, true, ON, &opt.lineup_to_parens}, | |
142 | {"l", PRO_INT, 78, 0, &opt.max_col}, | 142 | {"l", PRO_INT, 78, 0, &opt.max_col}, | |
143 | {"nbacc", PRO_BOOL, false, OFF, &opt.blanklines_around_conditional_compilation}, | 143 | {"nbacc", PRO_BOOL, false, OFF, &opt.blanklines_around_conditional_compilation}, | |
144 | {"nbadp", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations_at_proctop}, | 144 | {"nbadp", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations_at_proctop}, | |
145 | {"nbad", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations}, | 145 | {"nbad", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations}, | |
146 | {"nbap", PRO_BOOL, false, OFF, &opt.blanklines_after_procs}, | 146 | {"nbap", PRO_BOOL, false, OFF, &opt.blanklines_after_procs}, | |
147 | {"nbbb", PRO_BOOL, false, OFF, &opt.blanklines_before_blockcomments}, | 147 | {"nbbb", PRO_BOOL, false, OFF, &opt.blanklines_before_blockcomments}, | |
148 | {"nbc", PRO_BOOL, true, ON, &opt.leave_comma}, | 148 | {"nbc", PRO_BOOL, true, ON, &opt.leave_comma}, | |
149 | {"nbs", PRO_BOOL, false, OFF, &opt.Bill_Shannon}, | 149 | {"nbs", PRO_BOOL, false, OFF, &opt.Bill_Shannon}, | |
150 | {"ncdb", PRO_BOOL, true, OFF, &opt.comment_delimiter_on_blankline}, | 150 | {"ncdb", PRO_BOOL, true, OFF, &opt.comment_delimiter_on_blankline}, | |
151 | {"nce", PRO_BOOL, true, OFF, &opt.cuddle_else}, | 151 | {"nce", PRO_BOOL, true, OFF, &opt.cuddle_else}, | |
152 | {"ncs", PRO_BOOL, false, OFF, &opt.space_after_cast}, | 152 | {"ncs", PRO_BOOL, false, OFF, &opt.space_after_cast}, | |
153 | {"ndj", PRO_BOOL, false, OFF, &opt.ljust_decl}, | 153 | {"ndj", PRO_BOOL, false, OFF, &opt.ljust_decl}, | |
154 | {"neei", PRO_BOOL, false, OFF, &opt.extra_expression_indent}, | 154 | {"neei", PRO_BOOL, false, OFF, &opt.extra_expression_indent}, | |
155 | {"nei", PRO_BOOL, true, OFF, &opt.else_if}, | 155 | {"nei", PRO_BOOL, true, OFF, &opt.else_if}, | |
156 | {"nfbs", PRO_BOOL, true, OFF, &opt.function_brace_split}, | 156 | {"nfbs", PRO_BOOL, true, OFF, &opt.function_brace_split}, | |
157 | {"nfc1", PRO_BOOL, true, OFF, &opt.format_col1_comments}, | 157 | {"nfc1", PRO_BOOL, true, OFF, &opt.format_col1_comments}, | |
158 | {"nfcb", PRO_BOOL, true, OFF, &opt.format_block_comments}, | 158 | {"nfcb", PRO_BOOL, true, OFF, &opt.format_block_comments}, | |
159 | {"nip", PRO_BOOL, true, OFF, &opt.indent_parameters}, | 159 | {"nip", PRO_BOOL, true, OFF, &opt.indent_parameters}, | |
160 | {"nlpl", PRO_BOOL, false, OFF, &opt.lineup_to_parens_always}, | 160 | {"nlpl", PRO_BOOL, false, OFF, &opt.lineup_to_parens_always}, | |
161 | {"nlp", PRO_BOOL, true, OFF, &opt.lineup_to_parens}, | 161 | {"nlp", PRO_BOOL, true, OFF, &opt.lineup_to_parens}, | |
162 | {"npcs", PRO_BOOL, false, OFF, &opt.proc_calls_space}, | 162 | {"npcs", PRO_BOOL, false, OFF, &opt.proc_calls_space}, | |
163 | {"npro", PRO_SPECIAL, 0, IGN, 0}, | 163 | {"npro", PRO_SPECIAL, 0, IGN, 0}, | |
164 | {"npsl", PRO_BOOL, true, OFF, &opt.procnames_start_line}, | 164 | {"npsl", PRO_BOOL, true, OFF, &opt.procnames_start_line}, | |
165 | {"nsc", PRO_BOOL, true, OFF, &opt.star_comment_cont}, | 165 | {"nsc", PRO_BOOL, true, OFF, &opt.star_comment_cont}, | |
166 | {"nsob", PRO_BOOL, false, OFF, &opt.swallow_optional_blanklines}, | 166 | {"nsob", PRO_BOOL, false, OFF, &opt.swallow_optional_blanklines}, | |
167 | {"nut", PRO_BOOL, true, OFF, &opt.use_tabs}, | 167 | {"nut", PRO_BOOL, true, OFF, &opt.use_tabs}, | |
168 | {"nv", PRO_BOOL, false, OFF, &opt.verbose}, | 168 | {"nv", PRO_BOOL, false, OFF, &opt.verbose}, | |
169 | {"pcs", PRO_BOOL, false, ON, &opt.proc_calls_space}, | 169 | {"pcs", PRO_BOOL, false, ON, &opt.proc_calls_space}, | |
170 | {"psl", PRO_BOOL, true, ON, &opt.procnames_start_line}, | 170 | {"psl", PRO_BOOL, true, ON, &opt.procnames_start_line}, | |
171 | {"sc", PRO_BOOL, true, ON, &opt.star_comment_cont}, | 171 | {"sc", PRO_BOOL, true, ON, &opt.star_comment_cont}, | |
172 | {"sob", PRO_BOOL, false, ON, &opt.swallow_optional_blanklines}, | 172 | {"sob", PRO_BOOL, false, ON, &opt.swallow_optional_blanklines}, | |
173 | {"st", PRO_SPECIAL, 0, STDIN, 0}, | 173 | {"st", PRO_SPECIAL, 0, STDIN, 0}, | |
174 | {"ta", PRO_BOOL, false, ON, &opt.auto_typedefs}, | 174 | {"ta", PRO_BOOL, false, ON, &opt.auto_typedefs}, | |
175 | {"ts", PRO_INT, 8, 0, &opt.tabsize}, | 175 | {"ts", PRO_INT, 8, 0, &opt.tabsize}, | |
176 | {"ut", PRO_BOOL, true, ON, &opt.use_tabs}, | 176 | {"ut", PRO_BOOL, true, ON, &opt.use_tabs}, | |
177 | {"v", PRO_BOOL, false, ON, &opt.verbose}, | 177 | {"v", PRO_BOOL, false, ON, &opt.verbose}, | |
178 | /* whew! */ | 178 | /* whew! */ | |
179 | {0, 0, 0, 0, 0} | 179 | {0, 0, 0, 0, 0} | |
180 | }; | 180 | }; | |
181 | 181 | |||
182 | /* | 182 | /* | |
183 | * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments | 183 | * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments | |
184 | * given in these files. | 184 | * given in these files. | |
185 | */ | 185 | */ | |
186 | void | 186 | void | |
187 | set_profile(const char *profile_name) | 187 | set_profile(const char *profile_name) | |
188 | { | 188 | { | |
189 | FILE *f; | 189 | FILE *f; | |
190 | char fname[PATH_MAX]; | 190 | char fname[PATH_MAX]; | |
191 | static char prof[] = ".indent.pro"; | 191 | static char prof[] = ".indent.pro"; | |
192 | 192 | |||
193 | if (profile_name == NULL) | 193 | if (profile_name == NULL) | |
194 | snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); | 194 | snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof); | |
195 | else | 195 | else | |
196 | snprintf(fname, sizeof(fname), "%s", profile_name + 2); | 196 | snprintf(fname, sizeof(fname), "%s", profile_name + 2); | |
197 | if ((f = fopen(option_source = fname, "r")) != NULL) { | 197 | if ((f = fopen(option_source = fname, "r")) != NULL) { | |
198 | scan_profile(f); | 198 | scan_profile(f); | |
199 | (void) fclose(f); | 199 | (void) fclose(f); | |
200 | } | 200 | } | |
201 | if ((f = fopen(option_source = prof, "r")) != NULL) { | 201 | if ((f = fopen(option_source = prof, "r")) != NULL) { | |
202 | scan_profile(f); | 202 | scan_profile(f); | |
203 | (void) fclose(f); | 203 | (void) fclose(f); | |
204 | } | 204 | } | |
205 | option_source = "Command line"; | 205 | option_source = "Command line"; | |
206 | } | 206 | } | |
207 | 207 | |||
208 | static void | 208 | static void | |
209 | scan_profile(FILE *f) | 209 | scan_profile(FILE *f) | |
210 | { | 210 | { | |
211 | int comment_index, i; | 211 | int comment_index, i; | |
212 | char *p; | 212 | char *p; | |
213 | char buf[BUFSIZ]; | 213 | char buf[BUFSIZ]; | |
214 | 214 | |||
215 | while (1) { | 215 | while (1) { | |
216 | p = buf; | 216 | p = buf; | |
217 | comment_index = 0; | 217 | comment_index = 0; | |
218 | while ((i = getc(f)) != EOF) { | 218 | while ((i = getc(f)) != EOF) { | |
219 | if (i == '*' && !comment_index && p > buf && p[-1] == '/') { | 219 | if (i == '*' && !comment_index && p > buf && p[-1] == '/') { | |
220 | comment_index = p - buf; | 220 | comment_index = p - buf; | |
221 | *p++ = i; | 221 | *p++ = i; | |
222 | } else if (i == '/' && comment_index && p > buf && p[-1] == '*') { | 222 | } else if (i == '/' && comment_index && p > buf && p[-1] == '*') { | |
223 | p = buf + comment_index - 1; | 223 | p = buf + comment_index - 1; | |
224 | comment_index = 0; | 224 | comment_index = 0; | |
225 | } else if (isspace((unsigned char)i)) { | 225 | } else if (isspace((unsigned char)i)) { | |
226 | if (p > buf && !comment_index) | 226 | if (p > buf && !comment_index) | |
227 | break; | 227 | break; | |
228 | } else { | 228 | } else { | |
229 | *p++ = i; | 229 | *p++ = i; | |
230 | } | 230 | } | |
231 | } | 231 | } | |
232 | if (p != buf) { | 232 | if (p != buf) { | |
233 | *p++ = 0; | 233 | *p++ = 0; | |
234 | if (opt.verbose) | 234 | if (opt.verbose) | |
235 | printf("profile: %s\n", buf); | 235 | printf("profile: %s\n", buf); | |
236 | set_option(buf); | 236 | set_option(buf); | |
237 | } | 237 | } else if (i == EOF) | |
238 | else if (i == EOF) | |||
239 | return; | 238 | return; | |
240 | } | 239 | } | |
241 | } | 240 | } | |
242 | 241 | |||
243 | static const char * | 242 | static const char * | |
244 | eqin(const char *s1, const char *s2) | 243 | eqin(const char *s1, const char *s2) | |
245 | { | 244 | { | |
246 | while (*s1) { | 245 | while (*s1) { | |
247 | if (*s1++ != *s2++) | 246 | if (*s1++ != *s2++) | |
248 | return NULL; | 247 | return NULL; | |
249 | } | 248 | } | |
250 | return s2; | 249 | return s2; | |
251 | } | 250 | } | |
252 | 251 | |||
253 | /* | 252 | /* | |
254 | * Set the defaults. | 253 | * Set the defaults. | |
255 | */ | 254 | */ | |
256 | void | 255 | void | |
257 | set_defaults(void) | 256 | set_defaults(void) | |
258 | { | 257 | { | |
259 | /* | 258 | /* | |
260 | * Because ps.case_indent is a float, we can't initialize it from the | 259 | * Because ps.case_indent is a float, we can't initialize it from the | |
261 | * table: | 260 | * table: | |
262 | */ | 261 | */ | |
263 | opt.case_indent = 0.0F; /* -cli0.0 */ | 262 | opt.case_indent = 0.0F; /* -cli0.0 */ | |
264 | 263 | |||
265 | for (const struct pro *p = pro; p->p_name; p++) | 264 | for (const struct pro *p = pro; p->p_name; p++) | |
266 | if (p->p_type != PRO_SPECIAL) | 265 | if (p->p_type != PRO_SPECIAL) | |
267 | *p->p_obj = p->p_default; | 266 | *p->p_obj = p->p_default; | |
268 | } | 267 | } | |
269 | 268 | |||
270 | void | 269 | void | |
271 | set_option(char *arg) | 270 | set_option(char *arg) | |
272 | { | 271 | { | |
273 | const struct pro *p; | 272 | const struct pro *p; | |
274 | const char *param_start; | 273 | const char *param_start; | |
275 | 274 | |||
276 | arg++; /* ignore leading "-" */ | 275 | arg++; /* ignore leading "-" */ | |
277 | for (p = pro; p->p_name; p++) | 276 | for (p = pro; p->p_name; p++) | |
278 | if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL) | 277 | if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL) | |
279 | goto found; | 278 | goto found; | |
280 | errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); | 279 | errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); | |
281 | found: | 280 | found: | |
282 | switch (p->p_type) { | 281 | switch (p->p_type) { | |
283 | 282 | |||
284 | case PRO_SPECIAL: | 283 | case PRO_SPECIAL: | |
285 | switch (p->p_special) { | 284 | switch (p->p_special) { | |
286 | 285 | |||
287 | case IGN: | 286 | case IGN: | |
288 | break; | 287 | break; | |
289 | 288 | |||
290 | case CLI: | 289 | case CLI: | |
291 | if (*param_start == 0) | 290 | if (*param_start == 0) | |
292 | goto need_param; | 291 | goto need_param; | |
293 | opt.case_indent = atof(param_start); | 292 | opt.case_indent = atof(param_start); | |
294 | break; | 293 | break; | |
295 | 294 | |||
296 | case STDIN: | 295 | case STDIN: | |
297 | if (input == NULL) | 296 | if (input == NULL) | |
298 | input = stdin; | 297 | input = stdin; | |
299 | if (output == NULL) | 298 | if (output == NULL) | |
300 | output = stdout; | 299 | output = stdout; | |
301 | break; | 300 | break; | |
302 | 301 | |||
303 | case KEY: | 302 | case KEY: | |
304 | if (*param_start == 0) | 303 | if (*param_start == 0) | |
305 | goto need_param; | 304 | goto need_param; | |
306 | add_typename(param_start); | 305 | add_typename(param_start); | |
307 | break; | 306 | break; | |
308 | 307 | |||
309 | case KEY_FILE: | 308 | case KEY_FILE: | |
310 | if (*param_start == 0) | 309 | if (*param_start == 0) | |
311 | goto need_param; | 310 | goto need_param; | |
312 | add_typedefs_from_file(param_start); | 311 | add_typedefs_from_file(param_start); | |
313 | break; | 312 | break; | |
314 | 313 | |||
315 | case VERSION: | 314 | case VERSION: | |
316 | printf("FreeBSD indent %s\n", INDENT_VERSION); | 315 | printf("FreeBSD indent %s\n", INDENT_VERSION); | |
317 | exit(0); | 316 | exit(0); | |
318 | 317 | |||
319 | default: | 318 | default: | |
320 | errx(1, "set_option: internal error: p_special %d", p->p_special); | 319 | errx(1, "set_option: internal error: p_special %d", p->p_special); | |
321 | } | 320 | } | |
322 | break; | 321 | break; | |
323 | 322 | |||
324 | case PRO_BOOL: | 323 | case PRO_BOOL: | |
325 | if (p->p_special == OFF) | 324 | if (p->p_special == OFF) | |
326 | *p->p_obj = false; | 325 | *p->p_obj = false; | |
327 | else | 326 | else | |
328 | *p->p_obj = true; | 327 | *p->p_obj = true; | |
329 | break; | 328 | break; | |
330 | 329 | |||
331 | case PRO_INT: | 330 | case PRO_INT: | |
332 | if (!isdigit((unsigned char)*param_start)) { | 331 | if (!isdigit((unsigned char)*param_start)) { | |
333 | need_param: | 332 | need_param: | |
334 | errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name); | 333 | errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name); | |
335 | } | 334 | } | |
336 | *p->p_obj = atoi(param_start); | 335 | *p->p_obj = atoi(param_start); | |
337 | break; | 336 | break; | |
338 | 337 | |||
339 | default: | 338 | default: | |
340 | errx(1, "set_option: internal error: p_type %d", p->p_type); | 339 | errx(1, "set_option: internal error: p_type %d", p->p_type); | |
341 | } | 340 | } | |
342 | } | 341 | } | |
343 | 342 | |||
344 | void | 343 | void | |
345 | add_typedefs_from_file(const char *str) | 344 | add_typedefs_from_file(const char *str) | |
346 | { | 345 | { | |
347 | FILE *file; | 346 | FILE *file; | |
348 | char line[BUFSIZ]; | 347 | char line[BUFSIZ]; | |
349 | 348 | |||
350 | if ((file = fopen(str, "r")) == NULL) { | 349 | if ((file = fopen(str, "r")) == NULL) { | |
351 | fprintf(stderr, "indent: cannot open file %s\n", str); | 350 | fprintf(stderr, "indent: cannot open file %s\n", str); | |
352 | exit(1); | 351 | exit(1); | |
353 | } | 352 | } | |
354 | while ((fgets(line, BUFSIZ, file)) != NULL) { | 353 | while ((fgets(line, BUFSIZ, file)) != NULL) { | |
355 | /* Remove trailing whitespace */ | 354 | /* Remove trailing whitespace */ | |
356 | line[strcspn(line, " \t\n\r")] = '\0'; | 355 | line[strcspn(line, " \t\n\r")] = '\0'; | |
357 | add_typename(line); | 356 | add_typename(line); | |
358 | } | 357 | } | |
359 | fclose(file); | 358 | fclose(file); | |
360 | } | 359 | } |
--- src/usr.bin/indent/pr_comment.c 2021/03/11 22:32:06 1.18
+++ src/usr.bin/indent/pr_comment.c 2021/03/12 23:10:18 1.19
@@ -1,389 +1,381 @@ | @@ -1,389 +1,381 @@ | |||
1 | /* $NetBSD: pr_comment.c,v 1.18 2021/03/11 22:32:06 rillig Exp $ */ | 1 | /* $NetBSD: pr_comment.c,v 1.19 2021/03/12 23:10:18 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1980, 1993 | 7 | * Copyright (c) 1980, 1993 | |
8 | * The Regents of the University of California. All rights reserved. | 8 | * The Regents of the University of California. All rights reserved. | |
9 | * All rights reserved. | 9 | * All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #if 0 | 40 | #if 0 | |
41 | #ifndef lint | 41 | #ifndef lint | |
42 | static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; | 42 | static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; | |
43 | #endif /* not lint */ | 43 | #endif /* not lint */ | |
44 | #endif | 44 | #endif | |
45 | 45 | |||
46 | #include <sys/cdefs.h> | 46 | #include <sys/cdefs.h> | |
47 | #ifndef lint | 47 | #ifndef lint | |
48 | #if defined(__NetBSD__) | 48 | #if defined(__NetBSD__) | |
49 | __RCSID("$NetBSD: pr_comment.c,v 1.18 2021/03/11 22:32:06 rillig Exp $"); | 49 | __RCSID("$NetBSD: pr_comment.c,v 1.19 2021/03/12 23:10:18 rillig Exp $"); | |
50 | #elif defined(__FreeBSD__) | 50 | #elif defined(__FreeBSD__) | |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $"); | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $"); | |
52 | #endif | 52 | #endif | |
53 | #endif | 53 | #endif | |
54 | 54 | |||
55 | #include <err.h> | 55 | #include <err.h> | |
56 | #include <stdio.h> | 56 | #include <stdio.h> | |
57 | #include <stdlib.h> | 57 | #include <stdlib.h> | |
58 | #include <string.h> | 58 | #include <string.h> | |
59 | 59 | |||
60 | #include "indent.h" | 60 | #include "indent.h" | |
61 | 61 | |||
62 | static void | 62 | static void | |
63 | check_size_comment(size_t desired_size, char **last_bl_ptr) | 63 | check_size_comment(size_t desired_size, char **last_bl_ptr) | |
64 | { | 64 | { | |
65 | if (e_com + (desired_size) < l_com) | 65 | if (e_com + (desired_size) < l_com) | |
66 | return; | 66 | return; | |
67 | 67 | |||
68 | size_t nsize = l_com - s_com + 400 + desired_size; | 68 | size_t nsize = l_com - s_com + 400 + desired_size; | |
69 | size_t com_len = e_com - s_com; | 69 | size_t com_len = e_com - s_com; | |
70 | ssize_t blank_pos = *last_bl_ptr != NULL ? *last_bl_ptr - combuf : -1; | 70 | ssize_t blank_pos = *last_bl_ptr != NULL ? *last_bl_ptr - combuf : -1; | |
71 | combuf = realloc(combuf, nsize); | 71 | combuf = realloc(combuf, nsize); | |
72 | if (combuf == NULL) | 72 | if (combuf == NULL) | |
73 | err(1, NULL); | 73 | err(1, NULL); | |
74 | e_com = combuf + com_len + 1; | 74 | e_com = combuf + com_len + 1; | |
75 | if (blank_pos > 0) | 75 | if (blank_pos > 0) | |
76 | *last_bl_ptr = combuf + blank_pos; | 76 | *last_bl_ptr = combuf + blank_pos; | |
77 | l_com = combuf + nsize - 5; | 77 | l_com = combuf + nsize - 5; | |
78 | s_com = combuf + 1; | 78 | s_com = combuf + 1; | |
79 | } | 79 | } | |
80 | 80 | |||
81 | /* | 81 | /* | |
82 | * NAME: | 82 | * NAME: | |
83 | * pr_comment | 83 | * pr_comment | |
84 | * | 84 | * | |
85 | * FUNCTION: | 85 | * FUNCTION: | |
86 | * This routine takes care of scanning and printing comments. | 86 | * This routine takes care of scanning and printing comments. | |
87 | * | 87 | * | |
88 | * ALGORITHM: | 88 | * ALGORITHM: | |
89 | * 1) Decide where the comment should be aligned, and if lines should | 89 | * 1) Decide where the comment should be aligned, and if lines should | |
90 | * be broken. | 90 | * be broken. | |
91 | * 2) If lines should not be broken and filled, just copy up to end of | 91 | * 2) If lines should not be broken and filled, just copy up to end of | |
92 | * comment. | 92 | * comment. | |
93 | * 3) If lines should be filled, then scan thru input_buffer copying | 93 | * 3) If lines should be filled, then scan thru input_buffer copying | |
94 | * characters to com_buf. Remember where the last blank, tab, or | 94 | * characters to com_buf. Remember where the last blank, tab, or | |
95 | * newline was. When line is filled, print up to last blank and | 95 | * newline was. When line is filled, print up to last blank and | |
96 | * continue copying. | 96 | * continue copying. | |
97 | * | 97 | * | |
98 | * HISTORY: | 98 | * HISTORY: | |
99 | * November 1976 D A Willcox of CAC Initial coding | 99 | * November 1976 D A Willcox of CAC Initial coding | |
100 | * 12/6/76 D A Willcox of CAC Modification to handle | 100 | * 12/6/76 D A Willcox of CAC Modification to handle | |
101 | * UNIX-style comments | 101 | * UNIX-style comments | |
102 | * | 102 | * | |
103 | */ | 103 | */ | |
104 | 104 | |||
105 | /* | 105 | /* | |
106 | * this routine processes comments. It makes an attempt to keep comments from | 106 | * this routine processes comments. It makes an attempt to keep comments from | |
107 | * going over the max line length. If a line is too long, it moves everything | 107 | * going over the max line length. If a line is too long, it moves everything | |
108 | * from the last blank to the next comment line. Blanks and tabs from the | 108 | * from the last blank to the next comment line. Blanks and tabs from the | |
109 | * beginning of the input line are removed | 109 | * beginning of the input line are removed | |
110 | */ | 110 | */ | |
111 | 111 | |||
112 | void | 112 | void | |
113 | pr_comment(void) | 113 | pr_comment(void) | |
114 | { | 114 | { | |
115 | int now_col; /* column we are in now */ | 115 | int now_col; /* column we are in now */ | |
116 | int adj_max_col; /* Adjusted max_col for when we decide to | 116 | int adj_max_col; /* Adjusted max_col for when we decide to | |
117 | * spill comments over the right margin */ | 117 | * spill comments over the right margin */ | |
118 | char *last_bl; /* points to the last blank in the output | 118 | char *last_bl; /* points to the last blank in the output | |
119 | * buffer */ | 119 | * buffer */ | |
120 | char *t_ptr; /* used for moving string */ | 120 | char *t_ptr; /* used for moving string */ | |
121 | int break_delim = opt.comment_delimiter_on_blankline; | 121 | int break_delim = opt.comment_delimiter_on_blankline; | |
122 | int l_just_saw_decl = ps.just_saw_decl; | 122 | int l_just_saw_decl = ps.just_saw_decl; | |
123 | 123 | |||
124 | adj_max_col = opt.max_col; | 124 | adj_max_col = opt.max_col; | |
125 | ps.just_saw_decl = 0; | 125 | ps.just_saw_decl = 0; | |
126 | last_bl = NULL; /* no blanks found so far */ | 126 | last_bl = NULL; /* no blanks found so far */ | |
127 | ps.box_com = false; /* at first, assume that we are not in | 127 | ps.box_com = false; /* at first, assume that we are not in | |
128 | * a boxed comment or some other | 128 | * a boxed comment or some other | |
129 | * comment that should not be touched */ | 129 | * comment that should not be touched */ | |
130 | ++ps.out_coms; /* keep track of number of comments */ | 130 | ++ps.out_coms; /* keep track of number of comments */ | |
131 | 131 | |||
132 | /* Figure where to align and how to treat the comment */ | 132 | /* Figure where to align and how to treat the comment */ | |
133 | 133 | |||
134 | if (ps.col_1 && !opt.format_col1_comments) { /* if comment starts in column | 134 | if (ps.col_1 && !opt.format_col1_comments) { /* if comment starts in column | |
135 | * 1 it should not be touched */ | 135 | * 1 it should not be touched */ | |
136 | ps.box_com = true; | 136 | ps.box_com = true; | |
137 | break_delim = false; | 137 | break_delim = false; | |
138 | ps.com_col = 1; | 138 | ps.com_col = 1; | |
139 | } | 139 | } else { | |
140 | else { | |||
141 | if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' || | 140 | if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' || | |
142 | (*buf_ptr == '\n' && !opt.format_block_comments)) { | 141 | (*buf_ptr == '\n' && !opt.format_block_comments)) { | |
143 | ps.box_com = true; /* A comment with a '-' or '*' immediately | 142 | ps.box_com = true; /* A comment with a '-' or '*' immediately | |
144 | * after the /+* is assumed to be a boxed | 143 | * after the /+* is assumed to be a boxed | |
145 | * comment. A comment with a newline | 144 | * comment. A comment with a newline | |
146 | * immediately after the /+* is assumed to | 145 | * immediately after the /+* is assumed to | |
147 | * be a block comment and is treated as a | 146 | * be a block comment and is treated as a | |
148 | * box comment unless format_block_comments | 147 | * box comment unless format_block_comments | |
149 | * is nonzero (the default). */ | 148 | * is nonzero (the default). */ | |
150 | break_delim = false; | 149 | break_delim = false; | |
151 | } | 150 | } | |
152 | if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { | 151 | if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) { | |
153 | /* klg: check only if this line is blank */ | 152 | /* klg: check only if this line is blank */ | |
154 | /* | 153 | /* | |
155 | * If this (*and previous lines are*) blank, dont put comment way | 154 | * If this (*and previous lines are*) blank, dont put comment way | |
156 | * out at left | 155 | * out at left | |
157 | */ | 156 | */ | |
158 | ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1; | 157 | ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1; | |
159 | adj_max_col = opt.block_comment_max_col; | 158 | adj_max_col = opt.block_comment_max_col; | |
160 | if (ps.com_col <= 1) | 159 | if (ps.com_col <= 1) | |
161 | ps.com_col = 1 + !opt.format_col1_comments; | 160 | ps.com_col = 1 + !opt.format_col1_comments; | |
162 | } | 161 | } else { | |
163 | else { | |||
164 | int target_col; | 162 | int target_col; | |
165 | break_delim = false; | 163 | break_delim = false; | |
166 | if (s_code != e_code) | 164 | if (s_code != e_code) | |
167 | target_col = count_spaces(compute_code_target(), s_code); | 165 | target_col = count_spaces(compute_code_target(), s_code); | |
168 | else { | 166 | else { | |
169 | target_col = 1; | 167 | target_col = 1; | |
170 | if (s_lab != e_lab) | 168 | if (s_lab != e_lab) | |
171 | target_col = count_spaces(compute_label_target(), s_lab); | 169 | target_col = count_spaces(compute_label_target(), s_lab); | |
172 | } | 170 | } | |
173 | ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind; | 171 | ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind; | |
174 | if (ps.com_col <= target_col) | 172 | if (ps.com_col <= target_col) | |
175 | ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; | 173 | ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; | |
176 | if (ps.com_col + 24 > adj_max_col) | 174 | if (ps.com_col + 24 > adj_max_col) | |
177 | adj_max_col = ps.com_col + 24; | 175 | adj_max_col = ps.com_col + 24; | |
178 | } | 176 | } | |
179 | } | 177 | } | |
180 | if (ps.box_com) { | 178 | if (ps.box_com) { | |
181 | /* | 179 | /* | |
182 | * Find out how much indentation there was originally, because that | 180 | * Find out how much indentation there was originally, because that | |
183 | * much will have to be ignored by pad_output() in dump_line(). This | 181 | * much will have to be ignored by pad_output() in dump_line(). This | |
184 | * is a box comment, so nothing changes -- not even indentation. | 182 | * is a box comment, so nothing changes -- not even indentation. | |
185 | * | 183 | * | |
186 | * The comment we're about to read usually comes from in_buffer, | 184 | * The comment we're about to read usually comes from in_buffer, | |
187 | * unless it has been copied into save_com. | 185 | * unless it has been copied into save_com. | |
188 | */ | 186 | */ | |
189 | char *start; | 187 | char *start; | |
190 | 188 | |||
191 | start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? | 189 | start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? | |
192 | sc_buf : in_buffer; | 190 | sc_buf : in_buffer; | |
193 | ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2); | 191 | ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2); | |
194 | } | 192 | } else { | |
195 | else { | |||
196 | ps.n_comment_delta = 0; | 193 | ps.n_comment_delta = 0; | |
197 | while (*buf_ptr == ' ' || *buf_ptr == '\t') | 194 | while (*buf_ptr == ' ' || *buf_ptr == '\t') | |
198 | buf_ptr++; | 195 | buf_ptr++; | |
199 | } | 196 | } | |
200 | ps.comment_delta = 0; | 197 | ps.comment_delta = 0; | |
201 | *e_com++ = '/'; | 198 | *e_com++ = '/'; | |
202 | *e_com++ = e_token[-1]; | 199 | *e_com++ = e_token[-1]; | |
203 | if (*buf_ptr != ' ' && !ps.box_com) | 200 | if (*buf_ptr != ' ' && !ps.box_com) | |
204 | *e_com++ = ' '; | 201 | *e_com++ = ' '; | |
205 | 202 | |||
206 | /* | 203 | /* | |
207 | * Don't put a break delimiter if this is a one-liner that won't wrap. | 204 | * Don't put a break delimiter if this is a one-liner that won't wrap. | |
208 | */ | 205 | */ | |
209 | if (break_delim) | 206 | if (break_delim) | |
210 | for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { | 207 | for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { | |
211 | if (t_ptr >= buf_end) | 208 | if (t_ptr >= buf_end) | |
212 | fill_buffer(); | 209 | fill_buffer(); | |
213 | if (t_ptr[0] == '*' && t_ptr[1] == '/') { | 210 | if (t_ptr[0] == '*' && t_ptr[1] == '/') { | |
214 | if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2)) | 211 | if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2)) | |
215 | break_delim = false; | 212 | break_delim = false; | |
216 | break; | 213 | break; | |
217 | } | 214 | } | |
218 | } | 215 | } | |
219 | 216 | |||
220 | if (break_delim) { | 217 | if (break_delim) { | |
221 | char *t = e_com; | 218 | char *t = e_com; | |
222 | e_com = s_com + 2; | 219 | e_com = s_com + 2; | |
223 | *e_com = 0; | 220 | *e_com = 0; | |
224 | if (opt.blanklines_before_blockcomments && ps.last_token != lbrace) | 221 | if (opt.blanklines_before_blockcomments && ps.last_token != lbrace) | |
225 | prefix_blankline_requested = 1; | 222 | prefix_blankline_requested = 1; | |
226 | dump_line(); | 223 | dump_line(); | |
227 | e_com = s_com = t; | 224 | e_com = s_com = t; | |
228 | if (!ps.box_com && opt.star_comment_cont) | 225 | if (!ps.box_com && opt.star_comment_cont) | |
229 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 226 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
230 | } | 227 | } | |
231 | 228 | |||
232 | /* Start to copy the comment */ | 229 | /* Start to copy the comment */ | |
233 | 230 | |||
234 | while (1) { /* this loop will go until the comment is | 231 | while (1) { /* this loop will go until the comment is | |
235 | * copied */ | 232 | * copied */ | |
236 | switch (*buf_ptr) { /* this checks for various spcl cases */ | 233 | switch (*buf_ptr) { /* this checks for various spcl cases */ | |
237 | case 014: /* check for a form feed */ | 234 | case 014: /* check for a form feed */ | |
238 | check_size_comment(3, &last_bl); | 235 | check_size_comment(3, &last_bl); | |
239 | if (!ps.box_com) { /* in a text comment, break the line here */ | 236 | if (!ps.box_com) { /* in a text comment, break the line here */ | |
240 | ps.use_ff = true; | 237 | ps.use_ff = true; | |
241 | /* fix so dump_line uses a form feed */ | 238 | /* fix so dump_line uses a form feed */ | |
242 | dump_line(); | 239 | dump_line(); | |
243 | last_bl = NULL; | 240 | last_bl = NULL; | |
244 | if (!ps.box_com && opt.star_comment_cont) | 241 | if (!ps.box_com && opt.star_comment_cont) | |
245 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 242 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
246 | while (*++buf_ptr == ' ' || *buf_ptr == '\t') | 243 | while (*++buf_ptr == ' ' || *buf_ptr == '\t') | |
247 | ; | 244 | ; | |
248 | } | 245 | } else { | |
249 | else { | |||
250 | if (++buf_ptr >= buf_end) | 246 | if (++buf_ptr >= buf_end) | |
251 | fill_buffer(); | 247 | fill_buffer(); | |
252 | *e_com++ = 014; | 248 | *e_com++ = 014; | |
253 | } | 249 | } | |
254 | break; | 250 | break; | |
255 | 251 | |||
256 | case '\n': | 252 | case '\n': | |
257 | if (e_token[-1] == '/') { | 253 | if (e_token[-1] == '/') { | |
258 | ++line_no; | 254 | ++line_no; | |
259 | goto end_of_comment; | 255 | goto end_of_comment; | |
260 | } | 256 | } | |
261 | if (had_eof) { /* check for unexpected eof */ | 257 | if (had_eof) { /* check for unexpected eof */ | |
262 | printf("Unterminated comment\n"); | 258 | printf("Unterminated comment\n"); | |
263 | dump_line(); | 259 | dump_line(); | |
264 | return; | 260 | return; | |
265 | } | 261 | } | |
266 | last_bl = NULL; | 262 | last_bl = NULL; | |
267 | check_size_comment(4, &last_bl); | 263 | check_size_comment(4, &last_bl); | |
268 | if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, | 264 | if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, | |
269 | * we dont ignore the newline */ | 265 | * we dont ignore the newline */ | |
270 | if (s_com == e_com) | 266 | if (s_com == e_com) | |
271 | *e_com++ = ' '; | 267 | *e_com++ = ' '; | |
272 | if (!ps.box_com && e_com - s_com > 3) { | 268 | if (!ps.box_com && e_com - s_com > 3) { | |
273 | dump_line(); | 269 | dump_line(); | |
274 | if (opt.star_comment_cont) | 270 | if (opt.star_comment_cont) | |
275 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 271 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
276 | } | 272 | } | |
277 | dump_line(); | 273 | dump_line(); | |
278 | if (!ps.box_com && opt.star_comment_cont) | 274 | if (!ps.box_com && opt.star_comment_cont) | |
279 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 275 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
280 | } | 276 | } else { | |
281 | else { | |||
282 | ps.last_nl = 1; | 277 | ps.last_nl = 1; | |
283 | if (e_com[-1] == ' ' || e_com[-1] == '\t') | 278 | if (e_com[-1] == ' ' || e_com[-1] == '\t') | |
284 | last_bl = e_com - 1; | 279 | last_bl = e_com - 1; | |
285 | /* | 280 | /* | |
286 | * if there was a space at the end of the last line, remember | 281 | * if there was a space at the end of the last line, remember | |
287 | * where it was | 282 | * where it was | |
288 | */ | 283 | */ | |
289 | else { /* otherwise, insert one */ | 284 | else { /* otherwise, insert one */ | |
290 | last_bl = e_com; | 285 | last_bl = e_com; | |
291 | *e_com++ = ' '; | 286 | *e_com++ = ' '; | |
292 | } | 287 | } | |
293 | } | 288 | } | |
294 | ++line_no; /* keep track of input line number */ | 289 | ++line_no; /* keep track of input line number */ | |
295 | if (!ps.box_com) { | 290 | if (!ps.box_com) { | |
296 | int nstar = 1; | 291 | int nstar = 1; | |
297 | do { /* flush any blanks and/or tabs at start of | 292 | do { /* flush any blanks and/or tabs at start of | |
298 | * next line */ | 293 | * next line */ | |
299 | if (++buf_ptr >= buf_end) | 294 | if (++buf_ptr >= buf_end) | |
300 | fill_buffer(); | 295 | fill_buffer(); | |
301 | if (*buf_ptr == '*' && --nstar >= 0) { | 296 | if (*buf_ptr == '*' && --nstar >= 0) { | |
302 | if (++buf_ptr >= buf_end) | 297 | if (++buf_ptr >= buf_end) | |
303 | fill_buffer(); | 298 | fill_buffer(); | |
304 | if (*buf_ptr == '/') | 299 | if (*buf_ptr == '/') | |
305 | goto end_of_comment; | 300 | goto end_of_comment; | |
306 | } | 301 | } | |
307 | } while (*buf_ptr == ' ' || *buf_ptr == '\t'); | 302 | } while (*buf_ptr == ' ' || *buf_ptr == '\t'); | |
308 | } | 303 | } else if (++buf_ptr >= buf_end) | |
309 | else if (++buf_ptr >= buf_end) | |||
310 | fill_buffer(); | 304 | fill_buffer(); | |
311 | break; /* end of case for newline */ | 305 | break; /* end of case for newline */ | |
312 | 306 | |||
313 | case '*': /* must check for possibility of being at end | 307 | case '*': /* must check for possibility of being at end | |
314 | * of comment */ | 308 | * of comment */ | |
315 | if (++buf_ptr >= buf_end) /* get to next char after * */ | 309 | if (++buf_ptr >= buf_end) /* get to next char after * */ | |
316 | fill_buffer(); | 310 | fill_buffer(); | |
317 | check_size_comment(4, &last_bl); | 311 | check_size_comment(4, &last_bl); | |
318 | if (*buf_ptr == '/') { /* it is the end!!! */ | 312 | if (*buf_ptr == '/') { /* it is the end!!! */ | |
319 | end_of_comment: | 313 | end_of_comment: | |
320 | if (++buf_ptr >= buf_end) | 314 | if (++buf_ptr >= buf_end) | |
321 | fill_buffer(); | 315 | fill_buffer(); | |
322 | if (break_delim) { | 316 | if (break_delim) { | |
323 | if (e_com > s_com + 3) { | 317 | if (e_com > s_com + 3) | |
324 | dump_line(); | 318 | dump_line(); | |
325 | } | |||
326 | else | 319 | else | |
327 | s_com = e_com; | 320 | s_com = e_com; | |
328 | *e_com++ = ' '; | 321 | *e_com++ = ' '; | |
329 | } | 322 | } | |
330 | if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) | 323 | if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) | |
331 | *e_com++ = ' '; /* ensure blank before end */ | 324 | *e_com++ = ' '; /* ensure blank before end */ | |
332 | if (e_token[-1] == '/') | 325 | if (e_token[-1] == '/') | |
333 | *e_com++ = '\n', *e_com = '\0'; | 326 | *e_com++ = '\n', *e_com = '\0'; | |
334 | else | 327 | else | |
335 | *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; | 328 | *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; | |
336 | ps.just_saw_decl = l_just_saw_decl; | 329 | ps.just_saw_decl = l_just_saw_decl; | |
337 | return; | 330 | return; | |
338 | } | 331 | } else /* handle isolated '*' */ | |
339 | else /* handle isolated '*' */ | |||
340 | *e_com++ = '*'; | 332 | *e_com++ = '*'; | |
341 | break; | 333 | break; | |
342 | default: /* we have a random char */ | 334 | default: /* we have a random char */ | |
343 | now_col = count_spaces_until(ps.com_col, s_com, e_com); | 335 | now_col = count_spaces_until(ps.com_col, s_com, e_com); | |
344 | do { | 336 | do { | |
345 | check_size_comment(1, &last_bl); | 337 | check_size_comment(1, &last_bl); | |
346 | *e_com = *buf_ptr++; | 338 | *e_com = *buf_ptr++; | |
347 | if (buf_ptr >= buf_end) | 339 | if (buf_ptr >= buf_end) | |
348 | fill_buffer(); | 340 | fill_buffer(); | |
349 | if (*e_com == ' ' || *e_com == '\t') | 341 | if (*e_com == ' ' || *e_com == '\t') | |
350 | last_bl = e_com; /* remember we saw a blank */ | 342 | last_bl = e_com; /* remember we saw a blank */ | |
351 | ++e_com; | 343 | ++e_com; | |
352 | now_col++; | 344 | now_col++; | |
353 | } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && | 345 | } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && | |
354 | (now_col <= adj_max_col || !last_bl)); | 346 | (now_col <= adj_max_col || !last_bl)); | |
355 | ps.last_nl = false; | 347 | ps.last_nl = false; | |
356 | if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') { | 348 | if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') { | |
357 | /* | 349 | /* | |
358 | * the comment is too long, it must be broken up | 350 | * the comment is too long, it must be broken up | |
359 | */ | 351 | */ | |
360 | if (last_bl == NULL) { | 352 | if (last_bl == NULL) { | |
361 | dump_line(); | 353 | dump_line(); | |
362 | if (!ps.box_com && opt.star_comment_cont) | 354 | if (!ps.box_com && opt.star_comment_cont) | |
363 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 355 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
364 | break; | 356 | break; | |
365 | } | 357 | } | |
366 | *e_com = '\0'; | 358 | *e_com = '\0'; | |
367 | e_com = last_bl; | 359 | e_com = last_bl; | |
368 | dump_line(); | 360 | dump_line(); | |
369 | if (!ps.box_com && opt.star_comment_cont) | 361 | if (!ps.box_com && opt.star_comment_cont) | |
370 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 362 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
371 | for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; | 363 | for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; | |
372 | t_ptr++) | 364 | t_ptr++) | |
373 | ; | 365 | ; | |
374 | last_bl = NULL; | 366 | last_bl = NULL; | |
375 | /* | 367 | /* | |
376 | * t_ptr will be somewhere between e_com (dump_line() reset) | 368 | * t_ptr will be somewhere between e_com (dump_line() reset) | |
377 | * and l_com. So it's safe to copy byte by byte from t_ptr | 369 | * and l_com. So it's safe to copy byte by byte from t_ptr | |
378 | * to e_com without any check_size_comment(). | 370 | * to e_com without any check_size_comment(). | |
379 | */ | 371 | */ | |
380 | while (*t_ptr != '\0') { | 372 | while (*t_ptr != '\0') { | |
381 | if (*t_ptr == ' ' || *t_ptr == '\t') | 373 | if (*t_ptr == ' ' || *t_ptr == '\t') | |
382 | last_bl = e_com; | 374 | last_bl = e_com; | |
383 | *e_com++ = *t_ptr++; | 375 | *e_com++ = *t_ptr++; | |
384 | } | 376 | } | |
385 | } | 377 | } | |
386 | break; | 378 | break; | |
387 | } | 379 | } | |
388 | } | 380 | } | |
389 | } | 381 | } |
--- src/usr.bin/indent/indent.c 2021/03/12 00:15:34 1.44
+++ src/usr.bin/indent/indent.c 2021/03/12 23:10:18 1.45
@@ -1,1407 +1,1391 @@ | @@ -1,1407 +1,1391 @@ | |||
1 | /* $NetBSD: indent.c,v 1.44 2021/03/12 00:15:34 rillig Exp $ */ | 1 | /* $NetBSD: indent.c,v 1.45 2021/03/12 23:10:18 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. | 7 | * Copyright (c) 1976 Board of Trustees of the University of Illinois. | |
8 | * Copyright (c) 1980, 1993 | 8 | * Copyright (c) 1980, 1993 | |
9 | * The Regents of the University of California. All rights reserved. | 9 | * The Regents of the University of California. All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #if 0 | 40 | #if 0 | |
41 | #ifndef lint | 41 | #ifndef lint | |
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.44 2021/03/12 00:15:34 rillig Exp $"); | 49 | __RCSID("$NetBSD: indent.c,v 1.45 2021/03/12 23:10:18 rillig Exp $"); | |
50 | #elif defined(__FreeBSD__) | 50 | #elif defined(__FreeBSD__) | |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/indent.c 340138 2018-11-04 19:24:49Z oshogbo $"); | |
52 | #endif | 52 | #endif | |
53 | #endif | 53 | #endif | |
54 | 54 | |||
55 | #include <sys/param.h> | 55 | #include <sys/param.h> | |
56 | #if HAVE_CAPSICUM | 56 | #if HAVE_CAPSICUM | |
57 | #include <sys/capsicum.h> | 57 | #include <sys/capsicum.h> | |
58 | #include <capsicum_helpers.h> | 58 | #include <capsicum_helpers.h> | |
59 | #endif | 59 | #endif | |
60 | #include <err.h> | 60 | #include <err.h> | |
61 | #include <errno.h> | 61 | #include <errno.h> | |
62 | #include <fcntl.h> | 62 | #include <fcntl.h> | |
63 | #include <unistd.h> | 63 | #include <unistd.h> | |
64 | #include <stdio.h> | 64 | #include <stdio.h> | |
65 | #include <stdlib.h> | 65 | #include <stdlib.h> | |
66 | #include <string.h> | 66 | #include <string.h> | |
67 | #include <ctype.h> | 67 | #include <ctype.h> | |
68 | 68 | |||
69 | #include "indent.h" | 69 | #include "indent.h" | |
70 | 70 | |||
71 | struct options opt; | 71 | struct options opt; | |
72 | struct parser_state ps; | 72 | struct parser_state ps; | |
73 | 73 | |||
74 | char *labbuf; | 74 | char *labbuf; | |
75 | char *s_lab; | 75 | char *s_lab; | |
76 | char *e_lab; | 76 | char *e_lab; | |
77 | char *l_lab; | 77 | char *l_lab; | |
78 | 78 | |||
79 | char *codebuf; | 79 | char *codebuf; | |
80 | char *s_code; | 80 | char *s_code; | |
81 | char *e_code; | 81 | char *e_code; | |
82 | char *l_code; | 82 | char *l_code; | |
83 | 83 | |||
84 | char *combuf; | 84 | char *combuf; | |
85 | char *s_com; | 85 | char *s_com; | |
86 | char *e_com; | 86 | char *e_com; | |
87 | char *l_com; | 87 | char *l_com; | |
88 | 88 | |||
89 | char *tokenbuf; | 89 | char *tokenbuf; | |
90 | char *s_token; | 90 | char *s_token; | |
91 | char *e_token; | 91 | char *e_token; | |
92 | char *l_token; | 92 | char *l_token; | |
93 | 93 | |||
94 | char *in_buffer; | 94 | char *in_buffer; | |
95 | char *in_buffer_limit; | 95 | char *in_buffer_limit; | |
96 | char *buf_ptr; | 96 | char *buf_ptr; | |
97 | char *buf_end; | 97 | char *buf_end; | |
98 | 98 | |||
99 | char sc_buf[sc_size]; | 99 | char sc_buf[sc_size]; | |
100 | char *save_com; | 100 | char *save_com; | |
101 | char *sc_end; | 101 | char *sc_end; | |
102 | 102 | |||
103 | char *bp_save; | 103 | char *bp_save; | |
104 | char *be_save; | 104 | char *be_save; | |
105 | 105 | |||
106 | int found_err; | 106 | int found_err; | |
107 | int n_real_blanklines; | 107 | int n_real_blanklines; | |
108 | int prefix_blankline_requested; | 108 | int prefix_blankline_requested; | |
109 | int postfix_blankline_requested; | 109 | int postfix_blankline_requested; | |
110 | int break_comma; | 110 | int break_comma; | |
111 | float case_ind; | 111 | float case_ind; | |
112 | int code_lines; | 112 | int code_lines; | |
113 | int had_eof; | 113 | int had_eof; | |
114 | int line_no; | 114 | int line_no; | |
115 | int inhibit_formatting; | 115 | int inhibit_formatting; | |
116 | int suppress_blanklines; | 116 | int suppress_blanklines; | |
117 | 117 | |||
118 | int ifdef_level; | 118 | int ifdef_level; | |
119 | struct parser_state state_stack[5]; | 119 | struct parser_state state_stack[5]; | |
120 | struct parser_state match_state[5]; | 120 | struct parser_state match_state[5]; | |
121 | 121 | |||
122 | FILE *input; | 122 | FILE *input; | |
123 | FILE *output; | 123 | FILE *output; | |
124 | 124 | |||
125 | static void bakcopy(void); | 125 | static void bakcopy(void); | |
126 | static void indent_declaration(int, int); | 126 | static void indent_declaration(int, int); | |
127 | 127 | |||
128 | const char *in_name = "Standard Input"; /* will always point to name of input | 128 | const char *in_name = "Standard Input"; /* will always point to name of input | |
129 | * file */ | 129 | * file */ | |
130 | const char *out_name = "Standard Output"; /* will always point to name | 130 | const char *out_name = "Standard Output"; /* will always point to name | |
131 | * of output file */ | 131 | * of output file */ | |
132 | const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup | 132 | const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup | |
133 | * files */ | 133 | * files */ | |
134 | char bakfile[MAXPATHLEN] = ""; | 134 | char bakfile[MAXPATHLEN] = ""; | |
135 | 135 | |||
136 | static void | 136 | static void | |
137 | check_size_code(size_t desired_size) | 137 | check_size_code(size_t desired_size) | |
138 | { | 138 | { | |
139 | if (e_code + (desired_size) < l_code) | 139 | if (e_code + (desired_size) < l_code) | |
140 | return; | 140 | return; | |
141 | 141 | |||
142 | size_t nsize = l_code - s_code + 400 + desired_size; | 142 | size_t nsize = l_code - s_code + 400 + desired_size; | |
143 | size_t code_len = e_code - s_code; | 143 | size_t code_len = e_code - s_code; | |
144 | codebuf = realloc(codebuf, nsize); | 144 | codebuf = realloc(codebuf, nsize); | |
145 | if (codebuf == NULL) | 145 | if (codebuf == NULL) | |
146 | err(1, NULL); | 146 | err(1, NULL); | |
147 | e_code = codebuf + code_len + 1; | 147 | e_code = codebuf + code_len + 1; | |
148 | l_code = codebuf + nsize - 5; | 148 | l_code = codebuf + nsize - 5; | |
149 | s_code = codebuf + 1; | 149 | s_code = codebuf + 1; | |
150 | } | 150 | } | |
151 | 151 | |||
152 | static void | 152 | static void | |
153 | check_size_label(size_t desired_size) | 153 | check_size_label(size_t desired_size) | |
154 | { | 154 | { | |
155 | if (e_lab + (desired_size) < l_lab) | 155 | if (e_lab + (desired_size) < l_lab) | |
156 | return; | 156 | return; | |
157 | 157 | |||
158 | size_t nsize = l_lab - s_lab + 400 + desired_size; | 158 | size_t nsize = l_lab - s_lab + 400 + desired_size; | |
159 | size_t label_len = e_lab - s_lab; | 159 | size_t label_len = e_lab - s_lab; | |
160 | labbuf = realloc(labbuf, nsize); | 160 | labbuf = realloc(labbuf, nsize); | |
161 | if (labbuf == NULL) | 161 | if (labbuf == NULL) | |
162 | err(1, NULL); | 162 | err(1, NULL); | |
163 | e_lab = labbuf + label_len + 1; | 163 | e_lab = labbuf + label_len + 1; | |
164 | l_lab = labbuf + nsize - 5; | 164 | l_lab = labbuf + nsize - 5; | |
165 | s_lab = labbuf + 1; | 165 | s_lab = labbuf + 1; | |
166 | } | 166 | } | |
167 | 167 | |||
168 | #if HAVE_CAPSICUM | 168 | #if HAVE_CAPSICUM | |
169 | static void | 169 | static void | |
170 | init_capsicum(void) | 170 | init_capsicum(void) | |
171 | { | 171 | { | |
172 | cap_rights_t rights; | 172 | cap_rights_t rights; | |
173 | 173 | |||
174 | /* Restrict input/output descriptors and enter Capsicum sandbox. */ | 174 | /* Restrict input/output descriptors and enter Capsicum sandbox. */ | |
175 | cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); | 175 | cap_rights_init(&rights, CAP_FSTAT, CAP_WRITE); | |
176 | if (caph_rights_limit(fileno(output), &rights) < 0) | 176 | if (caph_rights_limit(fileno(output), &rights) < 0) | |
177 | err(EXIT_FAILURE, "unable to limit rights for %s", out_name); | 177 | err(EXIT_FAILURE, "unable to limit rights for %s", out_name); | |
178 | cap_rights_init(&rights, CAP_FSTAT, CAP_READ); | 178 | cap_rights_init(&rights, CAP_FSTAT, CAP_READ); | |
179 | if (caph_rights_limit(fileno(input), &rights) < 0) | 179 | if (caph_rights_limit(fileno(input), &rights) < 0) | |
180 | err(EXIT_FAILURE, "unable to limit rights for %s", in_name); | 180 | err(EXIT_FAILURE, "unable to limit rights for %s", in_name); | |
181 | if (caph_enter() < 0) | 181 | if (caph_enter() < 0) | |
182 | err(EXIT_FAILURE, "unable to enter capability mode"); | 182 | err(EXIT_FAILURE, "unable to enter capability mode"); | |
183 | } | 183 | } | |
184 | #endif | 184 | #endif | |
185 | 185 | |||
186 | static void | 186 | static void | |
187 | search_brace(token_type *inout_type_code, int *inout_force_nl, | 187 | search_brace(token_type *inout_type_code, int *inout_force_nl, | |
188 | int *inout_comment_buffered, int *inout_last_else) | 188 | int *inout_comment_buffered, int *inout_last_else) | |
189 | { | 189 | { | |
190 | while (ps.search_brace) { | 190 | while (ps.search_brace) { | |
191 | switch (*inout_type_code) { | 191 | switch (*inout_type_code) { | |
192 | case newline: | 192 | case newline: | |
193 | if (sc_end == NULL) { | 193 | if (sc_end == NULL) { | |
194 | save_com = sc_buf; | 194 | save_com = sc_buf; | |
195 | save_com[0] = save_com[1] = ' '; | 195 | save_com[0] = save_com[1] = ' '; | |
196 | sc_end = &save_com[2]; | 196 | sc_end = &save_com[2]; | |
197 | } | 197 | } | |
198 | *sc_end++ = '\n'; | 198 | *sc_end++ = '\n'; | |
199 | /* | 199 | /* | |
200 | * We may have inherited a force_nl == true from the previous | 200 | * We may have inherited a force_nl == true from the previous | |
201 | * token (like a semicolon). But once we know that a newline | 201 | * token (like a semicolon). But once we know that a newline | |
202 | * has been scanned in this loop, force_nl should be false. | 202 | * has been scanned in this loop, force_nl should be false. | |
203 | * | 203 | * | |
204 | * However, the force_nl == true must be preserved if newline | 204 | * However, the force_nl == true must be preserved if newline | |
205 | * is never scanned in this loop, so this assignment cannot be | 205 | * is never scanned in this loop, so this assignment cannot be | |
206 | * done earlier. | 206 | * done earlier. | |
207 | */ | 207 | */ | |
208 | *inout_force_nl = false; | 208 | *inout_force_nl = false; | |
209 | case form_feed: | 209 | case form_feed: | |
210 | break; | 210 | break; | |
211 | case comment: | 211 | case comment: | |
212 | if (sc_end == NULL) { | 212 | if (sc_end == NULL) { | |
213 | /* | 213 | /* | |
214 | * Copy everything from the start of the line, because | 214 | * Copy everything from the start of the line, because | |
215 | * pr_comment() will use that to calculate original | 215 | * pr_comment() will use that to calculate original | |
216 | * indentation of a boxed comment. | 216 | * indentation of a boxed comment. | |
217 | */ | 217 | */ | |
218 | memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4); | 218 | memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4); | |
219 | save_com = sc_buf + (buf_ptr - in_buffer - 4); | 219 | save_com = sc_buf + (buf_ptr - in_buffer - 4); | |
220 | save_com[0] = save_com[1] = ' '; | 220 | save_com[0] = save_com[1] = ' '; | |
221 | sc_end = &save_com[2]; | 221 | sc_end = &save_com[2]; | |
222 | } | 222 | } | |
223 | *inout_comment_buffered = true; | 223 | *inout_comment_buffered = true; | |
224 | *sc_end++ = '/'; /* copy in start of comment */ | 224 | *sc_end++ = '/'; /* copy in start of comment */ | |
225 | *sc_end++ = '*'; | 225 | *sc_end++ = '*'; | |
226 | for (;;) { /* loop until the end of the comment */ | 226 | for (;;) { /* loop until the end of the comment */ | |
227 | *sc_end = *buf_ptr++; | 227 | *sc_end = *buf_ptr++; | |
228 | if (buf_ptr >= buf_end) | 228 | if (buf_ptr >= buf_end) | |
229 | fill_buffer(); | 229 | fill_buffer(); | |
230 | if (*sc_end++ == '*' && *buf_ptr == '/') | 230 | if (*sc_end++ == '*' && *buf_ptr == '/') | |
231 | break; /* we are at end of comment */ | 231 | break; /* we are at end of comment */ | |
232 | if (sc_end >= &save_com[sc_size]) { /* check for temp buffer | 232 | if (sc_end >= &save_com[sc_size]) { /* check for temp buffer | |
233 | * overflow */ | 233 | * overflow */ | |
234 | diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); | 234 | diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); | |
235 | fflush(output); | 235 | fflush(output); | |
236 | exit(1); | 236 | exit(1); | |
237 | } | 237 | } | |
238 | } | 238 | } | |
239 | *sc_end++ = '/'; /* add ending slash */ | 239 | *sc_end++ = '/'; /* add ending slash */ | |
240 | if (++buf_ptr >= buf_end) /* get past / in buffer */ | 240 | if (++buf_ptr >= buf_end) /* get past / in buffer */ | |
241 | fill_buffer(); | 241 | fill_buffer(); | |
242 | break; | 242 | break; | |
243 | case lbrace: | 243 | case lbrace: | |
244 | /* | 244 | /* | |
245 | * Put KNF-style lbraces before the buffered up tokens and | 245 | * Put KNF-style lbraces before the buffered up tokens and | |
246 | * jump out of this loop in order to avoid copying the token | 246 | * jump out of this loop in order to avoid copying the token | |
247 | * again under the default case of the switch below. | 247 | * again under the default case of the switch below. | |
248 | */ | 248 | */ | |
249 | if (sc_end != NULL && opt.btype_2) { | 249 | if (sc_end != NULL && opt.btype_2) { | |
250 | save_com[0] = '{'; | 250 | save_com[0] = '{'; | |
251 | /* | 251 | /* | |
252 | * Originally the lbrace may have been alone on its own | 252 | * Originally the lbrace may have been alone on its own | |
253 | * line, but it will be moved into "the else's line", so | 253 | * line, but it will be moved into "the else's line", so | |
254 | * if there was a newline resulting from the "{" before, | 254 | * if there was a newline resulting from the "{" before, | |
255 | * it must be scanned now and ignored. | 255 | * it must be scanned now and ignored. | |
256 | */ | 256 | */ | |
257 | while (isspace((unsigned char)*buf_ptr)) { | 257 | while (isspace((unsigned char)*buf_ptr)) { | |
258 | if (++buf_ptr >= buf_end) | 258 | if (++buf_ptr >= buf_end) | |
259 | fill_buffer(); | 259 | fill_buffer(); | |
260 | if (*buf_ptr == '\n') | 260 | if (*buf_ptr == '\n') | |
261 | break; | 261 | break; | |
262 | } | 262 | } | |
263 | goto sw_buffer; | 263 | goto sw_buffer; | |
264 | } | 264 | } | |
265 | /* FALLTHROUGH */ | 265 | /* FALLTHROUGH */ | |
266 | default: /* it is the start of a normal statement */ | 266 | default: /* it is the start of a normal statement */ | |
267 | { | 267 | { | |
268 | int remove_newlines; | 268 | int remove_newlines; | |
269 | 269 | |||
270 | remove_newlines = | 270 | remove_newlines = | |
271 | /* "} else" */ | 271 | /* "} else" */ | |
272 | (*inout_type_code == keyword_do_else && *token == 'e' && | 272 | (*inout_type_code == keyword_do_else && *token == 'e' && | |
273 | e_code != s_code && e_code[-1] == '}') | 273 | e_code != s_code && e_code[-1] == '}') | |
274 | /* "else if" */ | 274 | /* "else if" */ | |
275 | || (*inout_type_code == keyword_for_if_while && | 275 | || (*inout_type_code == keyword_for_if_while && | |
276 | *token == 'i' && *inout_last_else && opt.else_if); | 276 | *token == 'i' && *inout_last_else && opt.else_if); | |
277 | if (remove_newlines) | 277 | if (remove_newlines) | |
278 | *inout_force_nl = false; | 278 | *inout_force_nl = false; | |
279 | if (sc_end == NULL) { /* ignore buffering if | 279 | if (sc_end == NULL) { /* ignore buffering if | |
280 | * comment wasn't saved up */ | 280 | * comment wasn't saved up */ | |
281 | ps.search_brace = false; | 281 | ps.search_brace = false; | |
282 | return; | 282 | return; | |
283 | } | 283 | } | |
284 | while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) { | 284 | while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) { | |
285 | sc_end--; | 285 | sc_end--; | |
286 | } | 286 | } | |
287 | if (opt.swallow_optional_blanklines || | 287 | if (opt.swallow_optional_blanklines || | |
288 | (!*inout_comment_buffered && remove_newlines)) { | 288 | (!*inout_comment_buffered && remove_newlines)) { | |
289 | *inout_force_nl = !remove_newlines; | 289 | *inout_force_nl = !remove_newlines; | |
290 | while (sc_end > save_com && sc_end[-1] == '\n') { | 290 | while (sc_end > save_com && sc_end[-1] == '\n') { | |
291 | sc_end--; | 291 | sc_end--; | |
292 | } | 292 | } | |
293 | } | 293 | } | |
294 | if (*inout_force_nl) { /* if we should insert a nl here, put | 294 | if (*inout_force_nl) { /* if we should insert a nl here, put | |
295 | * it into the buffer */ | 295 | * it into the buffer */ | |
296 | *inout_force_nl = false; | 296 | *inout_force_nl = false; | |
297 | --line_no; /* this will be re-increased when the | 297 | --line_no; /* this will be re-increased when the | |
298 | * newline is read from the buffer */ | 298 | * newline is read from the buffer */ | |
299 | *sc_end++ = '\n'; | 299 | *sc_end++ = '\n'; | |
300 | *sc_end++ = ' '; | 300 | *sc_end++ = ' '; | |
301 | if (opt.verbose) /* print error msg if the line was | 301 | if (opt.verbose) /* print error msg if the line was | |
302 | * not already broken */ | 302 | * not already broken */ | |
303 | diag(0, "Line broken"); | 303 | diag(0, "Line broken"); | |
304 | } | 304 | } | |
305 | for (const char *t_ptr = token; *t_ptr; ++t_ptr) | 305 | for (const char *t_ptr = token; *t_ptr; ++t_ptr) | |
306 | *sc_end++ = *t_ptr; | 306 | *sc_end++ = *t_ptr; | |
307 | 307 | |||
308 | sw_buffer: | 308 | sw_buffer: | |
309 | ps.search_brace = false; /* stop looking for start of stmt */ | 309 | ps.search_brace = false; /* stop looking for start of stmt */ | |
310 | bp_save = buf_ptr; /* save current input buffer */ | 310 | bp_save = buf_ptr; /* save current input buffer */ | |
311 | be_save = buf_end; | 311 | be_save = buf_end; | |
312 | buf_ptr = save_com; /* fix so that subsequent calls to | 312 | buf_ptr = save_com; /* fix so that subsequent calls to | |
313 | * lexi will take tokens out of save_com */ | 313 | * lexi will take tokens out of save_com */ | |
314 | *sc_end++ = ' '; /* add trailing blank, just in case */ | 314 | *sc_end++ = ' '; /* add trailing blank, just in case */ | |
315 | buf_end = sc_end; | 315 | buf_end = sc_end; | |
316 | sc_end = NULL; | 316 | sc_end = NULL; | |
317 | break; | 317 | break; | |
318 | } | 318 | } | |
319 | } /* end of switch */ | 319 | } /* end of switch */ | |
320 | /* | 320 | /* | |
321 | * We must make this check, just in case there was an unexpected | 321 | * We must make this check, just in case there was an unexpected | |
322 | * EOF. | 322 | * EOF. | |
323 | */ | 323 | */ | |
324 | if (*inout_type_code != end_of_file) { | 324 | if (*inout_type_code != end_of_file) { | |
325 | /* | 325 | /* | |
326 | * The only intended purpose of calling lexi() below is to | 326 | * The only intended purpose of calling lexi() below is to | |
327 | * categorize the next token in order to decide whether to | 327 | * categorize the next token in order to decide whether to | |
328 | * continue buffering forthcoming tokens. Once the buffering | 328 | * continue buffering forthcoming tokens. Once the buffering | |
329 | * is over, lexi() will be called again elsewhere on all of | 329 | * is over, lexi() will be called again elsewhere on all of | |
330 | * the tokens - this time for normal processing. | 330 | * the tokens - this time for normal processing. | |
331 | * | 331 | * | |
332 | * Calling it for this purpose is a bug, because lexi() also | 332 | * Calling it for this purpose is a bug, because lexi() also | |
333 | * changes the parser state and discards leading whitespace, | 333 | * changes the parser state and discards leading whitespace, | |
334 | * which is needed mostly for comment-related considerations. | 334 | * which is needed mostly for comment-related considerations. | |
335 | * | 335 | * | |
336 | * Work around the former problem by giving lexi() a copy of | 336 | * Work around the former problem by giving lexi() a copy of | |
337 | * the current parser state and discard it if the call turned | 337 | * the current parser state and discard it if the call turned | |
338 | * out to be just a look ahead. | 338 | * out to be just a look ahead. | |
339 | * | 339 | * | |
340 | * Work around the latter problem by copying all whitespace | 340 | * Work around the latter problem by copying all whitespace | |
341 | * characters into the buffer so that the later lexi() call | 341 | * characters into the buffer so that the later lexi() call | |
342 | * will read them. | 342 | * will read them. | |
343 | */ | 343 | */ | |
344 | if (sc_end != NULL) { | 344 | if (sc_end != NULL) { | |
345 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | 345 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | |
346 | *sc_end++ = *buf_ptr++; | 346 | *sc_end++ = *buf_ptr++; | |
347 | if (sc_end >= &save_com[sc_size]) { | 347 | if (sc_end >= &save_com[sc_size]) { | |
348 | errx(1, "input too long"); | 348 | errx(1, "input too long"); | |
349 | } | 349 | } | |
350 | } | 350 | } | |
351 | if (buf_ptr >= buf_end) { | 351 | if (buf_ptr >= buf_end) { | |
352 | fill_buffer(); | 352 | fill_buffer(); | |
353 | } | 353 | } | |
354 | } | 354 | } | |
355 | 355 | |||
356 | struct parser_state transient_state; | 356 | struct parser_state transient_state; | |
357 | transient_state = ps; | 357 | transient_state = ps; | |
358 | *inout_type_code = lexi(&transient_state); /* read another token */ | 358 | *inout_type_code = lexi(&transient_state); /* read another token */ | |
359 | if (*inout_type_code != newline && *inout_type_code != form_feed && | 359 | if (*inout_type_code != newline && *inout_type_code != form_feed && | |
360 | *inout_type_code != comment && !transient_state.search_brace) { | 360 | *inout_type_code != comment && !transient_state.search_brace) { | |
361 | ps = transient_state; | 361 | ps = transient_state; | |
362 | } | 362 | } | |
363 | } | 363 | } | |
364 | } | 364 | } | |
365 | 365 | |||
366 | *inout_last_else = 0; | 366 | *inout_last_else = 0; | |
367 | } | 367 | } | |
368 | 368 | |||
369 | int | 369 | int | |
370 | main(int argc, char **argv) | 370 | main(int argc, char **argv) | |
371 | { | 371 | { | |
372 | int dec_ind; /* current indentation for declarations */ | 372 | int dec_ind; /* current indentation for declarations */ | |
373 | int di_stack[20]; /* a stack of structure indentation levels */ | 373 | int di_stack[20]; /* a stack of structure indentation levels */ | |
374 | int force_nl; /* when true, code must be broken */ | 374 | int force_nl; /* when true, code must be broken */ | |
375 | token_type hd_type = end_of_file; /* used to store type of stmt | 375 | token_type hd_type = end_of_file; /* used to store type of stmt | |
376 | * for if (...), for (...), etc */ | 376 | * for if (...), for (...), etc */ | |
377 | int i; /* local loop counter */ | 377 | int i; /* local loop counter */ | |
378 | int scase; /* set to true when we see a case, so we will | 378 | int scase; /* set to true when we see a case, so we will | |
379 | * know what to do with the following colon */ | 379 | * know what to do with the following colon */ | |
380 | int sp_sw; /* when true, we are in the expression of | 380 | int sp_sw; /* when true, we are in the expression of | |
381 | * if(...), while(...), etc. */ | 381 | * if(...), while(...), etc. */ | |
382 | int squest; /* when this is positive, we have seen a ? | 382 | int squest; /* when this is positive, we have seen a ? | |
383 | * without the matching : in a <c>?<s>:<s> | 383 | * without the matching : in a <c>?<s>:<s> | |
384 | * construct */ | 384 | * construct */ | |
385 | int tabs_to_var; /* true if using tabs to indent to var name */ | 385 | int tabs_to_var; /* true if using tabs to indent to var name */ | |
386 | token_type type_code; /* returned by lexi */ | 386 | token_type type_code; /* returned by lexi */ | |
387 | 387 | |||
388 | int last_else = 0; /* true iff last keyword was an else */ | 388 | int last_else = 0; /* true iff last keyword was an else */ | |
389 | const char *profile_name = NULL; | 389 | const char *profile_name = NULL; | |
390 | const char *envval = NULL; | 390 | const char *envval = NULL; | |
391 | 391 | |||
392 | /*-----------------------------------------------*\ | 392 | /*-----------------------------------------------*\ | |
393 | | INITIALIZATION | | 393 | | INITIALIZATION | | |
394 | \*-----------------------------------------------*/ | 394 | \*-----------------------------------------------*/ | |
395 | 395 | |||
396 | found_err = 0; | 396 | found_err = 0; | |
397 | 397 | |||
398 | ps.p_stack[0] = stmt; /* this is the parser's stack */ | 398 | ps.p_stack[0] = stmt; /* this is the parser's stack */ | |
399 | ps.last_nl = true; /* this is true if the last thing scanned was | 399 | ps.last_nl = true; /* this is true if the last thing scanned was | |
400 | * a newline */ | 400 | * a newline */ | |
401 | ps.last_token = semicolon; | 401 | ps.last_token = semicolon; | |
402 | combuf = malloc(bufsize); | 402 | combuf = malloc(bufsize); | |
403 | if (combuf == NULL) | 403 | if (combuf == NULL) | |
404 | err(1, NULL); | 404 | err(1, NULL); | |
405 | labbuf = malloc(bufsize); | 405 | labbuf = malloc(bufsize); | |
406 | if (labbuf == NULL) | 406 | if (labbuf == NULL) | |
407 | err(1, NULL); | 407 | err(1, NULL); | |
408 | codebuf = malloc(bufsize); | 408 | codebuf = malloc(bufsize); | |
409 | if (codebuf == NULL) | 409 | if (codebuf == NULL) | |
410 | err(1, NULL); | 410 | err(1, NULL); | |
411 | tokenbuf = malloc(bufsize); | 411 | tokenbuf = malloc(bufsize); | |
412 | if (tokenbuf == NULL) | 412 | if (tokenbuf == NULL) | |
413 | err(1, NULL); | 413 | err(1, NULL); | |
414 | alloc_typenames(); | 414 | alloc_typenames(); | |
415 | init_constant_tt(); | 415 | init_constant_tt(); | |
416 | l_com = combuf + bufsize - 5; | 416 | l_com = combuf + bufsize - 5; | |
417 | l_lab = labbuf + bufsize - 5; | 417 | l_lab = labbuf + bufsize - 5; | |
418 | l_code = codebuf + bufsize - 5; | 418 | l_code = codebuf + bufsize - 5; | |
419 | l_token = tokenbuf + bufsize - 5; | 419 | l_token = tokenbuf + bufsize - 5; | |
420 | combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and | 420 | combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and | |
421 | * comment buffers */ | 421 | * comment buffers */ | |
422 | combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; | 422 | combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; | |
423 | opt.else_if = 1; /* Default else-if special processing to on */ | 423 | opt.else_if = 1; /* Default else-if special processing to on */ | |
424 | s_lab = e_lab = labbuf + 1; | 424 | s_lab = e_lab = labbuf + 1; | |
425 | s_code = e_code = codebuf + 1; | 425 | s_code = e_code = codebuf + 1; | |
426 | s_com = e_com = combuf + 1; | 426 | s_com = e_com = combuf + 1; | |
427 | s_token = e_token = tokenbuf + 1; | 427 | s_token = e_token = tokenbuf + 1; | |
428 | 428 | |||
429 | in_buffer = malloc(10); | 429 | in_buffer = malloc(10); | |
430 | if (in_buffer == NULL) | 430 | if (in_buffer == NULL) | |
431 | err(1, NULL); | 431 | err(1, NULL); | |
432 | in_buffer_limit = in_buffer + 8; | 432 | in_buffer_limit = in_buffer + 8; | |
433 | buf_ptr = buf_end = in_buffer; | 433 | buf_ptr = buf_end = in_buffer; | |
434 | line_no = 1; | 434 | line_no = 1; | |
435 | had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; | 435 | had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; | |
436 | sp_sw = force_nl = false; | 436 | sp_sw = force_nl = false; | |
437 | ps.in_or_st = false; | 437 | ps.in_or_st = false; | |
438 | ps.bl_line = true; | 438 | ps.bl_line = true; | |
439 | dec_ind = 0; | 439 | dec_ind = 0; | |
440 | di_stack[ps.dec_nest = 0] = 0; | 440 | di_stack[ps.dec_nest = 0] = 0; | |
441 | ps.want_blank = ps.in_stmt = ps.ind_stmt = false; | 441 | ps.want_blank = ps.in_stmt = ps.ind_stmt = false; | |
442 | 442 | |||
443 | scase = ps.pcase = false; | 443 | scase = ps.pcase = false; | |
444 | squest = 0; | 444 | squest = 0; | |
445 | sc_end = NULL; | 445 | sc_end = NULL; | |
446 | bp_save = NULL; | 446 | bp_save = NULL; | |
447 | be_save = NULL; | 447 | be_save = NULL; | |
448 | 448 | |||
449 | output = NULL; | 449 | output = NULL; | |
450 | tabs_to_var = 0; | 450 | tabs_to_var = 0; | |
451 | 451 | |||
452 | envval = getenv("SIMPLE_BACKUP_SUFFIX"); | 452 | envval = getenv("SIMPLE_BACKUP_SUFFIX"); | |
453 | if (envval) | 453 | if (envval) | |
454 | simple_backup_suffix = envval; | 454 | simple_backup_suffix = envval; | |
455 | 455 | |||
456 | /*--------------------------------------------------*\ | 456 | /*--------------------------------------------------*\ | |
457 | | COMMAND LINE SCAN | | 457 | | COMMAND LINE SCAN | | |
458 | \*--------------------------------------------------*/ | 458 | \*--------------------------------------------------*/ | |
459 | 459 | |||
460 | #ifdef undef | 460 | #ifdef undef | |
461 | max_col = 78; /* -l78 */ | 461 | max_col = 78; /* -l78 */ | |
462 | lineup_to_parens = 1; /* -lp */ | 462 | lineup_to_parens = 1; /* -lp */ | |
463 | lineup_to_parens_always = 0; /* -nlpl */ | 463 | lineup_to_parens_always = 0; /* -nlpl */ | |
464 | ps.ljust_decl = 0; /* -ndj */ | 464 | ps.ljust_decl = 0; /* -ndj */ | |
465 | ps.com_ind = 33; /* -c33 */ | 465 | ps.com_ind = 33; /* -c33 */ | |
466 | star_comment_cont = 1; /* -sc */ | 466 | star_comment_cont = 1; /* -sc */ | |
467 | ps.ind_size = 8; /* -i8 */ | 467 | ps.ind_size = 8; /* -i8 */ | |
468 | verbose = 0; | 468 | verbose = 0; | |
469 | ps.decl_indent = 16; /* -di16 */ | 469 | ps.decl_indent = 16; /* -di16 */ | |
470 | ps.local_decl_indent = -1; /* if this is not set to some nonnegative value | 470 | ps.local_decl_indent = -1; /* if this is not set to some nonnegative value | |
471 | * by an arg, we will set this equal to | 471 | * by an arg, we will set this equal to | |
472 | * ps.decl_ind */ | 472 | * ps.decl_ind */ | |
473 | ps.indent_parameters = 1; /* -ip */ | 473 | ps.indent_parameters = 1; /* -ip */ | |
474 | ps.decl_com_ind = 0; /* if this is not set to some positive value | 474 | ps.decl_com_ind = 0; /* if this is not set to some positive value | |
475 | * by an arg, we will set this equal to | 475 | * by an arg, we will set this equal to | |
476 | * ps.com_ind */ | 476 | * ps.com_ind */ | |
477 | btype_2 = 1; /* -br */ | 477 | btype_2 = 1; /* -br */ | |
478 | cuddle_else = 1; /* -ce */ | 478 | cuddle_else = 1; /* -ce */ | |
479 | ps.unindent_displace = 0; /* -d0 */ | 479 | ps.unindent_displace = 0; /* -d0 */ | |
480 | ps.case_indent = 0; /* -cli0 */ | 480 | ps.case_indent = 0; /* -cli0 */ | |
481 | format_block_comments = 1; /* -fcb */ | 481 | format_block_comments = 1; /* -fcb */ | |
482 | format_col1_comments = 1; /* -fc1 */ | 482 | format_col1_comments = 1; /* -fc1 */ | |
483 | procnames_start_line = 1; /* -psl */ | 483 | procnames_start_line = 1; /* -psl */ | |
484 | proc_calls_space = 0; /* -npcs */ | 484 | proc_calls_space = 0; /* -npcs */ | |
485 | comment_delimiter_on_blankline = 1; /* -cdb */ | 485 | comment_delimiter_on_blankline = 1; /* -cdb */ | |
486 | ps.leave_comma = 1; /* -nbc */ | 486 | ps.leave_comma = 1; /* -nbc */ | |
487 | #endif | 487 | #endif | |
488 | 488 | |||
489 | for (i = 1; i < argc; ++i) | 489 | for (i = 1; i < argc; ++i) | |
490 | if (strcmp(argv[i], "-npro") == 0) | 490 | if (strcmp(argv[i], "-npro") == 0) | |
491 | break; | 491 | break; | |
492 | else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') | 492 | else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') | |
493 | profile_name = argv[i]; /* non-empty -P (set profile) */ | 493 | profile_name = argv[i]; /* non-empty -P (set profile) */ | |
494 | set_defaults(); | 494 | set_defaults(); | |
495 | if (i >= argc) | 495 | if (i >= argc) | |
496 | set_profile(profile_name); | 496 | set_profile(profile_name); | |
497 | 497 | |||
498 | for (i = 1; i < argc; ++i) { | 498 | for (i = 1; i < argc; ++i) { | |
499 | 499 | |||
500 | /* | 500 | /* | |
501 | * look thru args (if any) for changes to defaults | 501 | * look thru args (if any) for changes to defaults | |
502 | */ | 502 | */ | |
503 | if (argv[i][0] != '-') {/* no flag on parameter */ | 503 | if (argv[i][0] != '-') {/* no flag on parameter */ | |
504 | if (input == NULL) { /* we must have the input file */ | 504 | if (input == NULL) { /* we must have the input file */ | |
505 | in_name = argv[i]; /* remember name of input file */ | 505 | in_name = argv[i]; /* remember name of input file */ | |
506 | input = fopen(in_name, "r"); | 506 | input = fopen(in_name, "r"); | |
507 | if (input == NULL) /* check for open error */ | 507 | if (input == NULL) /* check for open error */ | |
508 | err(1, "%s", in_name); | 508 | err(1, "%s", in_name); | |
509 | continue; | 509 | continue; | |
510 | } | 510 | } else if (output == NULL) { /* we have the output file */ | |
511 | else if (output == NULL) { /* we have the output file */ | |||
512 | out_name = argv[i]; /* remember name of output file */ | 511 | out_name = argv[i]; /* remember name of output file */ | |
513 | if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite | 512 | if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite | |
514 | * the file */ | 513 | * the file */ | |
515 | errx(1, "input and output files must be different"); | 514 | errx(1, "input and output files must be different"); | |
516 | } | 515 | } | |
517 | output = fopen(out_name, "w"); | 516 | output = fopen(out_name, "w"); | |
518 | if (output == NULL) /* check for create error */ | 517 | if (output == NULL) /* check for create error */ | |
519 | err(1, "%s", out_name); | 518 | err(1, "%s", out_name); | |
520 | continue; | 519 | continue; | |
521 | } | 520 | } | |
522 | errx(1, "unknown parameter: %s", argv[i]); | 521 | errx(1, "unknown parameter: %s", argv[i]); | |
523 | } | 522 | } else | |
524 | else | |||
525 | set_option(argv[i]); | 523 | set_option(argv[i]); | |
526 | } /* end of for */ | 524 | } /* end of for */ | |
527 | if (input == NULL) | 525 | if (input == NULL) | |
528 | input = stdin; | 526 | input = stdin; | |
529 | if (output == NULL) { | 527 | if (output == NULL) { | |
530 | if (input == stdin) | 528 | if (input == stdin) | |
531 | output = stdout; | 529 | output = stdout; | |
532 | else { | 530 | else { | |
533 | out_name = in_name; | 531 | out_name = in_name; | |
534 | bakcopy(); | 532 | bakcopy(); | |
535 | } | 533 | } | |
536 | } | 534 | } | |
537 | 535 | |||
538 | #if HAVE_CAPSICUM | 536 | #if HAVE_CAPSICUM | |
539 | init_capsicum(); | 537 | init_capsicum(); | |
540 | #endif | 538 | #endif | |
541 | 539 | |||
542 | if (opt.com_ind <= 1) | 540 | if (opt.com_ind <= 1) | |
543 | opt.com_ind = 2; /* don't put normal comments before column 2 */ | 541 | opt.com_ind = 2; /* don't put normal comments before column 2 */ | |
544 | if (opt.block_comment_max_col <= 0) | 542 | if (opt.block_comment_max_col <= 0) | |
545 | opt.block_comment_max_col = opt.max_col; | 543 | opt.block_comment_max_col = opt.max_col; | |
546 | if (opt.local_decl_indent < 0) /* if not specified by user, set this */ | 544 | if (opt.local_decl_indent < 0) /* if not specified by user, set this */ | |
547 | opt.local_decl_indent = opt.decl_indent; | 545 | opt.local_decl_indent = opt.decl_indent; | |
548 | if (opt.decl_com_ind <= 0) /* if not specified by user, set this */ | 546 | if (opt.decl_com_ind <= 0) /* if not specified by user, set this */ | |
549 | opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind; | 547 | opt.decl_com_ind = opt.ljust_decl ? (opt.com_ind <= 10 ? 2 : opt.com_ind - 8) : opt.com_ind; | |
550 | if (opt.continuation_indent == 0) | 548 | if (opt.continuation_indent == 0) | |
551 | opt.continuation_indent = opt.ind_size; | 549 | opt.continuation_indent = opt.ind_size; | |
552 | fill_buffer(); /* get first batch of stuff into input buffer */ | 550 | fill_buffer(); /* get first batch of stuff into input buffer */ | |
553 | 551 | |||
554 | parse(semicolon); | 552 | parse(semicolon); | |
555 | { | 553 | { | |
556 | char *p = buf_ptr; | 554 | char *p = buf_ptr; | |
557 | int col = 1; | 555 | int col = 1; | |
558 | 556 | |||
559 | while (1) { | 557 | while (1) { | |
560 | if (*p == ' ') | 558 | if (*p == ' ') | |
561 | col++; | 559 | col++; | |
562 | else if (*p == '\t') | 560 | else if (*p == '\t') | |
563 | col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; | 561 | col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; | |
564 | else | 562 | else | |
565 | break; | 563 | break; | |
566 | p++; | 564 | p++; | |
567 | } | 565 | } | |
568 | if (col > opt.ind_size) | 566 | if (col > opt.ind_size) | |
569 | ps.ind_level = ps.i_l_follow = col / opt.ind_size; | 567 | ps.ind_level = ps.i_l_follow = col / opt.ind_size; | |
570 | } | 568 | } | |
571 | 569 | |||
572 | /* | 570 | /* | |
573 | * START OF MAIN LOOP | 571 | * START OF MAIN LOOP | |
574 | */ | 572 | */ | |
575 | 573 | |||
576 | while (1) { /* this is the main loop. it will go until we | 574 | while (1) { /* this is the main loop. it will go until we | |
577 | * reach eof */ | 575 | * reach eof */ | |
578 | int comment_buffered = false; | 576 | int comment_buffered = false; | |
579 | 577 | |||
580 | type_code = lexi(&ps); /* lexi reads one token. The actual | 578 | type_code = lexi(&ps); /* lexi reads one token. The actual | |
581 | * characters read are stored in "token". lexi | 579 | * characters read are stored in "token". lexi | |
582 | * returns a code indicating the type of token */ | 580 | * returns a code indicating the type of token */ | |
583 | 581 | |||
584 | /* | 582 | /* | |
585 | * The following code moves newlines and comments following an if (), | 583 | * The following code moves newlines and comments following an if (), | |
586 | * while (), else, etc. up to the start of the following stmt to | 584 | * while (), else, etc. up to the start of the following stmt to | |
587 | * a buffer. This allows proper handling of both kinds of brace | 585 | * a buffer. This allows proper handling of both kinds of brace | |
588 | * placement (-br, -bl) and cuddling "else" (-ce). | 586 | * placement (-br, -bl) and cuddling "else" (-ce). | |
589 | */ | 587 | */ | |
590 | search_brace(&type_code, &force_nl, &comment_buffered, &last_else); | 588 | search_brace(&type_code, &force_nl, &comment_buffered, &last_else); | |
591 | 589 | |||
592 | if (type_code == end_of_file) { /* we got eof */ | 590 | if (type_code == end_of_file) { /* we got eof */ | |
593 | if (s_lab != e_lab || s_code != e_code | 591 | if (s_lab != e_lab || s_code != e_code | |
594 | || s_com != e_com) /* must dump end of line */ | 592 | || s_com != e_com) /* must dump end of line */ | |
595 | dump_line(); | 593 | dump_line(); | |
596 | if (ps.tos > 1) /* check for balanced braces */ | 594 | if (ps.tos > 1) /* check for balanced braces */ | |
597 | diag(1, "Stuff missing from end of file"); | 595 | diag(1, "Stuff missing from end of file"); | |
598 | 596 | |||
599 | if (opt.verbose) { | 597 | if (opt.verbose) { | |
600 | printf("There were %d output lines and %d comments\n", | 598 | printf("There were %d output lines and %d comments\n", | |
601 | ps.out_lines, ps.out_coms); | 599 | ps.out_lines, ps.out_coms); | |
602 | printf("(Lines with comments)/(Lines with code): %6.3f\n", | 600 | printf("(Lines with comments)/(Lines with code): %6.3f\n", | |
603 | (1.0 * ps.com_lines) / code_lines); | 601 | (1.0 * ps.com_lines) / code_lines); | |
604 | } | 602 | } | |
605 | fflush(output); | 603 | fflush(output); | |
606 | exit(found_err); | 604 | exit(found_err); | |
607 | } | 605 | } | |
608 | if ( | 606 | if ( | |
609 | (type_code != comment) && | 607 | (type_code != comment) && | |
610 | (type_code != newline) && | 608 | (type_code != newline) && | |
611 | (type_code != preprocessing) && | 609 | (type_code != preprocessing) && | |
612 | (type_code != form_feed)) { | 610 | (type_code != form_feed)) { | |
613 | if (force_nl && | 611 | if (force_nl && | |
614 | (type_code != semicolon) && | 612 | (type_code != semicolon) && | |
615 | (type_code != lbrace || !opt.btype_2)) { | 613 | (type_code != lbrace || !opt.btype_2)) { | |
616 | /* we should force a broken line here */ | 614 | /* we should force a broken line here */ | |
617 | if (opt.verbose) | 615 | if (opt.verbose) | |
618 | diag(0, "Line broken"); | 616 | diag(0, "Line broken"); | |
619 | dump_line(); | 617 | dump_line(); | |
620 | ps.want_blank = false; /* dont insert blank at line start */ | 618 | ps.want_blank = false; /* dont insert blank at line start */ | |
621 | force_nl = false; | 619 | force_nl = false; | |
622 | } | 620 | } | |
623 | ps.in_stmt = true; /* turn on flag which causes an extra level of | 621 | ps.in_stmt = true; /* turn on flag which causes an extra level of | |
624 | * indentation. this is turned off by a ; or | 622 | * indentation. this is turned off by a ; or | |
625 | * '}' */ | 623 | * '}' */ | |
626 | if (s_com != e_com) { /* the turkey has embedded a comment | 624 | if (s_com != e_com) { /* the turkey has embedded a comment | |
627 | * in a line. fix it */ | 625 | * in a line. fix it */ | |
628 | int len = e_com - s_com; | 626 | int len = e_com - s_com; | |
629 | 627 | |||
630 | check_size_code(len + 3); | 628 | check_size_code(len + 3); | |
631 | *e_code++ = ' '; | 629 | *e_code++ = ' '; | |
632 | memcpy(e_code, s_com, len); | 630 | memcpy(e_code, s_com, len); | |
633 | e_code += len; | 631 | e_code += len; | |
634 | *e_code++ = ' '; | 632 | *e_code++ = ' '; | |
635 | *e_code = '\0'; /* null terminate code sect */ | 633 | *e_code = '\0'; /* null terminate code sect */ | |
636 | ps.want_blank = false; | 634 | ps.want_blank = false; | |
637 | e_com = s_com; | 635 | e_com = s_com; | |
638 | } | 636 | } | |
639 | } | 637 | } else if (type_code != comment) /* preserve force_nl thru a comment */ | |
640 | else if (type_code != comment) /* preserve force_nl thru a comment */ | |||
641 | force_nl = false; /* cancel forced newline after newline, form | 638 | force_nl = false; /* cancel forced newline after newline, form | |
642 | * feed, etc */ | 639 | * feed, etc */ | |
643 | 640 | |||
644 | 641 | |||
645 | 642 | |||
646 | /*-----------------------------------------------------*\ | 643 | /*-----------------------------------------------------*\ | |
647 | | do switch on type of token scanned | | 644 | | do switch on type of token scanned | | |
648 | \*-----------------------------------------------------*/ | 645 | \*-----------------------------------------------------*/ | |
649 | check_size_code(3); /* maximum number of increments of e_code | 646 | check_size_code(3); /* maximum number of increments of e_code | |
650 | * before the next check_size_code or | 647 | * before the next check_size_code or | |
651 | * dump_line() is 2. After that there's the | 648 | * dump_line() is 2. After that there's the | |
652 | * final increment for the null character. */ | 649 | * final increment for the null character. */ | |
653 | switch (type_code) { /* now, decide what to do with the token */ | 650 | switch (type_code) { /* now, decide what to do with the token */ | |
654 | 651 | |||
655 | case form_feed: /* found a form feed in line */ | 652 | case form_feed: /* found a form feed in line */ | |
656 | ps.use_ff = true; /* a form feed is treated much like a newline */ | 653 | ps.use_ff = true; /* a form feed is treated much like a newline */ | |
657 | dump_line(); | 654 | dump_line(); | |
658 | ps.want_blank = false; | 655 | ps.want_blank = false; | |
659 | break; | 656 | break; | |
660 | 657 | |||
661 | case newline: | 658 | case newline: | |
662 | if (ps.last_token != comma || ps.p_l_follow > 0 | 659 | if (ps.last_token != comma || ps.p_l_follow > 0 | |
663 | || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { | 660 | || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { | |
664 | dump_line(); | 661 | dump_line(); | |
665 | ps.want_blank = false; | 662 | ps.want_blank = false; | |
666 | } | 663 | } | |
667 | ++line_no; /* keep track of input line number */ | 664 | ++line_no; /* keep track of input line number */ | |
668 | break; | 665 | break; | |
669 | 666 | |||
670 | case lparen: /* got a '(' or '[' */ | 667 | case lparen: /* got a '(' or '[' */ | |
671 | /* count parens to make Healy happy */ | 668 | /* count parens to make Healy happy */ | |
672 | if (++ps.p_l_follow == nitems(ps.paren_indents)) { | 669 | if (++ps.p_l_follow == nitems(ps.paren_indents)) { | |
673 | diag(0, "Reached internal limit of %zu unclosed parens", | 670 | diag(0, "Reached internal limit of %zu unclosed parens", | |
674 | nitems(ps.paren_indents)); | 671 | nitems(ps.paren_indents)); | |
675 | ps.p_l_follow--; | 672 | ps.p_l_follow--; | |
676 | } | 673 | } | |
677 | if (*token == '[') | 674 | if (*token == '[') | |
678 | /* not a function pointer declaration or a function call */; | 675 | /* not a function pointer declaration or a function call */; | |
679 | else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && | 676 | else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && | |
680 | ps.procname[0] == '\0' && ps.paren_level == 0) { | 677 | ps.procname[0] == '\0' && ps.paren_level == 0) { | |
681 | /* function pointer declarations */ | 678 | /* function pointer declarations */ | |
682 | indent_declaration(dec_ind, tabs_to_var); | 679 | indent_declaration(dec_ind, tabs_to_var); | |
683 | ps.dumped_decl_indent = true; | 680 | ps.dumped_decl_indent = true; | |
684 | } | 681 | } else if (ps.want_blank && | |
685 | else if (ps.want_blank && | |||
686 | ((ps.last_token != ident && ps.last_token != funcname) || | 682 | ((ps.last_token != ident && ps.last_token != funcname) || | |
687 | opt.proc_calls_space || | 683 | opt.proc_calls_space || | |
688 | (ps.keyword == rw_sizeof ? opt.Bill_Shannon : | 684 | (ps.keyword == rw_sizeof ? opt.Bill_Shannon : | |
689 | ps.keyword != rw_0 && ps.keyword != rw_offsetof))) | 685 | ps.keyword != rw_0 && ps.keyword != rw_offsetof))) | |
690 | *e_code++ = ' '; | 686 | *e_code++ = ' '; | |
691 | ps.want_blank = false; | 687 | ps.want_blank = false; | |
692 | *e_code++ = token[0]; | 688 | *e_code++ = token[0]; | |
693 | ps.paren_indents[ps.p_l_follow - 1] = count_spaces_until(1, s_code, e_code) - 1; | 689 | ps.paren_indents[ps.p_l_follow - 1] = count_spaces_until(1, s_code, e_code) - 1; | |
694 | if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent | 690 | if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent | |
695 | && ps.paren_indents[0] < 2 * opt.ind_size) | 691 | && ps.paren_indents[0] < 2 * opt.ind_size) | |
696 | ps.paren_indents[0] = 2 * opt.ind_size; | 692 | ps.paren_indents[0] = 2 * opt.ind_size; | |
697 | if (ps.in_or_st && *token == '(' && ps.tos <= 2) { | 693 | if (ps.in_or_st && *token == '(' && ps.tos <= 2) { | |
698 | /* | 694 | /* | |
699 | * this is a kluge to make sure that declarations will be | 695 | * this is a kluge to make sure that declarations will be | |
700 | * aligned right if proc decl has an explicit type on it, i.e. | 696 | * aligned right if proc decl has an explicit type on it, i.e. | |
701 | * "int a(x) {..." | 697 | * "int a(x) {..." | |
702 | */ | 698 | */ | |
703 | parse(semicolon); /* I said this was a kluge... */ | 699 | parse(semicolon); /* I said this was a kluge... */ | |
704 | ps.in_or_st = false; /* turn off flag for structure decl or | 700 | ps.in_or_st = false; /* turn off flag for structure decl or | |
705 | * initialization */ | 701 | * initialization */ | |
706 | } | 702 | } | |
707 | /* parenthesized type following sizeof or offsetof is not a cast */ | 703 | /* parenthesized type following sizeof or offsetof is not a cast */ | |
708 | if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) | 704 | if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) | |
709 | ps.not_cast_mask |= 1 << ps.p_l_follow; | 705 | ps.not_cast_mask |= 1 << ps.p_l_follow; | |
710 | break; | 706 | break; | |
711 | 707 | |||
712 | case rparen: /* got a ')' or ']' */ | 708 | case rparen: /* got a ')' or ']' */ | |
713 | if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { | 709 | if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { | |
714 | ps.last_u_d = true; | 710 | ps.last_u_d = true; | |
715 | ps.cast_mask &= (1 << ps.p_l_follow) - 1; | 711 | ps.cast_mask &= (1 << ps.p_l_follow) - 1; | |
716 | ps.want_blank = opt.space_after_cast; | 712 | ps.want_blank = opt.space_after_cast; | |
717 | } else | 713 | } else | |
718 | ps.want_blank = true; | 714 | ps.want_blank = true; | |
719 | ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; | 715 | ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; | |
720 | if (--ps.p_l_follow < 0) { | 716 | if (--ps.p_l_follow < 0) { | |
721 | ps.p_l_follow = 0; | 717 | ps.p_l_follow = 0; | |
722 | diag(0, "Extra %c", *token); | 718 | diag(0, "Extra %c", *token); | |
723 | } | 719 | } | |
724 | if (e_code == s_code) /* if the paren starts the line */ | 720 | if (e_code == s_code) /* if the paren starts the line */ | |
725 | ps.paren_level = ps.p_l_follow; /* then indent it */ | 721 | ps.paren_level = ps.p_l_follow; /* then indent it */ | |
726 | 722 | |||
727 | *e_code++ = token[0]; | 723 | *e_code++ = token[0]; | |
728 | 724 | |||
729 | if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if | 725 | if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if | |
730 | * (...), or some such */ | 726 | * (...), or some such */ | |
731 | sp_sw = false; | 727 | sp_sw = false; | |
732 | force_nl = true; /* must force newline after if */ | 728 | force_nl = true; /* must force newline after if */ | |
733 | ps.last_u_d = true; /* inform lexi that a following | 729 | ps.last_u_d = true; /* inform lexi that a following | |
734 | * operator is unary */ | 730 | * operator is unary */ | |
735 | ps.in_stmt = false; /* dont use stmt continuation | 731 | ps.in_stmt = false; /* dont use stmt continuation | |
736 | * indentation */ | 732 | * indentation */ | |
737 | 733 | |||
738 | parse(hd_type); /* let parser worry about if, or whatever */ | 734 | parse(hd_type); /* let parser worry about if, or whatever */ | |
739 | } | 735 | } | |
740 | ps.search_brace = opt.btype_2; /* this should ensure that | 736 | ps.search_brace = opt.btype_2; /* this should ensure that | |
741 | * constructs such as main(){...} | 737 | * constructs such as main(){...} | |
742 | * and int[]{...} have their braces | 738 | * and int[]{...} have their braces | |
743 | * put in the right place */ | 739 | * put in the right place */ | |
744 | break; | 740 | break; | |
745 | 741 | |||
746 | case unary_op: /* this could be any unary operation */ | 742 | case unary_op: /* this could be any unary operation */ | |
747 | if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && | 743 | if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && | |
748 | ps.procname[0] == '\0' && ps.paren_level == 0) { | 744 | ps.procname[0] == '\0' && ps.paren_level == 0) { | |
749 | /* pointer declarations */ | 745 | /* pointer declarations */ | |
750 | 746 | |||
751 | /* | 747 | /* | |
752 | * if this is a unary op in a declaration, we should indent | 748 | * if this is a unary op in a declaration, we should indent | |
753 | * this token | 749 | * this token | |
754 | */ | 750 | */ | |
755 | for (i = 0; token[i]; ++i) | 751 | for (i = 0; token[i]; ++i) | |
756 | /* find length of token */; | 752 | /* find length of token */; | |
757 | indent_declaration(dec_ind - i, tabs_to_var); | 753 | indent_declaration(dec_ind - i, tabs_to_var); | |
758 | ps.dumped_decl_indent = true; | 754 | ps.dumped_decl_indent = true; | |
759 | } | 755 | } else if (ps.want_blank) | |
760 | else if (ps.want_blank) | |||
761 | *e_code++ = ' '; | 756 | *e_code++ = ' '; | |
762 | 757 | |||
763 | { | 758 | { | |
764 | int len = e_token - s_token; | 759 | int len = e_token - s_token; | |
765 | 760 | |||
766 | check_size_code(len); | 761 | check_size_code(len); | |
767 | memcpy(e_code, token, len); | 762 | memcpy(e_code, token, len); | |
768 | e_code += len; | 763 | e_code += len; | |
769 | } | 764 | } | |
770 | ps.want_blank = false; | 765 | ps.want_blank = false; | |
771 | break; | 766 | break; | |
772 | 767 | |||
773 | case binary_op: /* any binary operation */ | 768 | case binary_op: /* any binary operation */ | |
774 | { | 769 | { | |
775 | int len = e_token - s_token; | 770 | int len = e_token - s_token; | |
776 | 771 | |||
777 | check_size_code(len + 1); | 772 | check_size_code(len + 1); | |
778 | if (ps.want_blank) | 773 | if (ps.want_blank) | |
779 | *e_code++ = ' '; | 774 | *e_code++ = ' '; | |
780 | memcpy(e_code, token, len); | 775 | memcpy(e_code, token, len); | |
781 | e_code += len; | 776 | e_code += len; | |
782 | } | 777 | } | |
783 | ps.want_blank = true; | 778 | ps.want_blank = true; | |
784 | break; | 779 | break; | |
785 | 780 | |||
786 | case postfix_op: /* got a trailing ++ or -- */ | 781 | case postfix_op: /* got a trailing ++ or -- */ | |
787 | *e_code++ = token[0]; | 782 | *e_code++ = token[0]; | |
788 | *e_code++ = token[1]; | 783 | *e_code++ = token[1]; | |
789 | ps.want_blank = true; | 784 | ps.want_blank = true; | |
790 | break; | 785 | break; | |
791 | 786 | |||
792 | case question: /* got a ? */ | 787 | case question: /* got a ? */ | |
793 | squest++; /* this will be used when a later colon | 788 | squest++; /* this will be used when a later colon | |
794 | * appears so we can distinguish the | 789 | * appears so we can distinguish the | |
795 | * <c>?<n>:<n> construct */ | 790 | * <c>?<n>:<n> construct */ | |
796 | if (ps.want_blank) | 791 | if (ps.want_blank) | |
797 | *e_code++ = ' '; | 792 | *e_code++ = ' '; | |
798 | *e_code++ = '?'; | 793 | *e_code++ = '?'; | |
799 | ps.want_blank = true; | 794 | ps.want_blank = true; | |
800 | break; | 795 | break; | |
801 | 796 | |||
802 | case case_label: /* got word 'case' or 'default' */ | 797 | case case_label: /* got word 'case' or 'default' */ | |
803 | scase = true; /* so we can process the later colon properly */ | 798 | scase = true; /* so we can process the later colon properly */ | |
804 | goto copy_id; | 799 | goto copy_id; | |
805 | 800 | |||
806 | case colon: /* got a ':' */ | 801 | case colon: /* got a ':' */ | |
807 | if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ | 802 | if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */ | |
808 | --squest; | 803 | --squest; | |
809 | if (ps.want_blank) | 804 | if (ps.want_blank) | |
810 | *e_code++ = ' '; | 805 | *e_code++ = ' '; | |
811 | *e_code++ = ':'; | 806 | *e_code++ = ':'; | |
812 | ps.want_blank = true; | 807 | ps.want_blank = true; | |
813 | break; | 808 | break; | |
814 | } | 809 | } | |
815 | if (ps.in_or_st) { | 810 | if (ps.in_or_st) { | |
816 | *e_code++ = ':'; | 811 | *e_code++ = ':'; | |
817 | ps.want_blank = false; | 812 | ps.want_blank = false; | |
818 | break; | 813 | break; | |
819 | } | 814 | } | |
820 | ps.in_stmt = false; /* seeing a label does not imply we are in a | 815 | ps.in_stmt = false; /* seeing a label does not imply we are in a | |
821 | * stmt */ | 816 | * stmt */ | |
822 | /* | 817 | /* | |
823 | * turn everything so far into a label | 818 | * turn everything so far into a label | |
824 | */ | 819 | */ | |
825 | { | 820 | { | |
826 | int len = e_code - s_code; | 821 | int len = e_code - s_code; | |
827 | 822 | |||
828 | check_size_label(len + 3); | 823 | check_size_label(len + 3); | |
829 | memcpy(e_lab, s_code, len); | 824 | memcpy(e_lab, s_code, len); | |
830 | e_lab += len; | 825 | e_lab += len; | |
831 | *e_lab++ = ':'; | 826 | *e_lab++ = ':'; | |
832 | *e_lab = '\0'; | 827 | *e_lab = '\0'; | |
833 | e_code = s_code; | 828 | e_code = s_code; | |
834 | } | 829 | } | |
835 | force_nl = ps.pcase = scase; /* ps.pcase will be used by | 830 | force_nl = ps.pcase = scase; /* ps.pcase will be used by | |
836 | * dump_line to decide how to | 831 | * dump_line to decide how to | |
837 | * indent the label. force_nl | 832 | * indent the label. force_nl | |
838 | * will force a case n: to be | 833 | * will force a case n: to be | |
839 | * on a line by itself */ | 834 | * on a line by itself */ | |
840 | scase = false; | 835 | scase = false; | |
841 | ps.want_blank = false; | 836 | ps.want_blank = false; | |
842 | break; | 837 | break; | |
843 | 838 | |||
844 | case semicolon: /* got a ';' */ | 839 | case semicolon: /* got a ';' */ | |
845 | if (ps.dec_nest == 0) | 840 | if (ps.dec_nest == 0) | |
846 | ps.in_or_st = false; /* we are not in an initialization or | 841 | ps.in_or_st = false; /* we are not in an initialization or | |
847 | * structure declaration */ | 842 | * structure declaration */ | |
848 | scase = false; /* these will only need resetting in an error */ | 843 | scase = false; /* these will only need resetting in an error */ | |
849 | squest = 0; | 844 | squest = 0; | |
850 | if (ps.last_token == rparen) | 845 | if (ps.last_token == rparen) | |
851 | ps.in_parameter_declaration = 0; | 846 | ps.in_parameter_declaration = 0; | |
852 | ps.cast_mask = 0; | 847 | ps.cast_mask = 0; | |
853 | ps.not_cast_mask = 0; | 848 | ps.not_cast_mask = 0; | |
854 | ps.block_init = 0; | 849 | ps.block_init = 0; | |
855 | ps.block_init_level = 0; | 850 | ps.block_init_level = 0; | |
856 | ps.just_saw_decl--; | 851 | ps.just_saw_decl--; | |
857 | 852 | |||
858 | if (ps.in_decl && s_code == e_code && !ps.block_init && | 853 | if (ps.in_decl && s_code == e_code && !ps.block_init && | |
859 | !ps.dumped_decl_indent && ps.paren_level == 0) { | 854 | !ps.dumped_decl_indent && ps.paren_level == 0) { | |
860 | /* indent stray semicolons in declarations */ | 855 | /* indent stray semicolons in declarations */ | |
861 | indent_declaration(dec_ind - 1, tabs_to_var); | 856 | indent_declaration(dec_ind - 1, tabs_to_var); | |
862 | ps.dumped_decl_indent = true; | 857 | ps.dumped_decl_indent = true; | |
863 | } | 858 | } | |
864 | 859 | |||
865 | ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level | 860 | ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level | |
866 | * structure declaration, we | 861 | * structure declaration, we | |
867 | * arent any more */ | 862 | * arent any more */ | |
868 | 863 | |||
869 | if ((!sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { | 864 | if ((!sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { | |
870 | 865 | |||
871 | /* | 866 | /* | |
872 | * This should be true iff there were unbalanced parens in the | 867 | * This should be true iff there were unbalanced parens in the | |
873 | * stmt. It is a bit complicated, because the semicolon might | 868 | * stmt. It is a bit complicated, because the semicolon might | |
874 | * be in a for stmt | 869 | * be in a for stmt | |
875 | */ | 870 | */ | |
876 | diag(1, "Unbalanced parens"); | 871 | diag(1, "Unbalanced parens"); | |
877 | ps.p_l_follow = 0; | 872 | ps.p_l_follow = 0; | |
878 | if (sp_sw) { /* this is a check for an if, while, etc. with | 873 | if (sp_sw) { /* this is a check for an if, while, etc. with | |
879 | * unbalanced parens */ | 874 | * unbalanced parens */ | |
880 | sp_sw = false; | 875 | sp_sw = false; | |
881 | parse(hd_type); /* dont lose the if, or whatever */ | 876 | parse(hd_type); /* dont lose the if, or whatever */ | |
882 | } | 877 | } | |
883 | } | 878 | } | |
884 | *e_code++ = ';'; | 879 | *e_code++ = ';'; | |
885 | ps.want_blank = true; | 880 | ps.want_blank = true; | |
886 | ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the | 881 | ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the | |
887 | * middle of a stmt */ | 882 | * middle of a stmt */ | |
888 | 883 | |||
889 | if (!sp_sw) { /* if not if for (;;) */ | 884 | if (!sp_sw) { /* if not if for (;;) */ | |
890 | parse(semicolon); /* let parser know about end of stmt */ | 885 | parse(semicolon); /* let parser know about end of stmt */ | |
891 | force_nl = true;/* force newline after an end of stmt */ | 886 | force_nl = true;/* force newline after an end of stmt */ | |
892 | } | 887 | } | |
893 | break; | 888 | break; | |
894 | 889 | |||
895 | case lbrace: /* got a '{' */ | 890 | case lbrace: /* got a '{' */ | |
896 | ps.in_stmt = false; /* dont indent the {} */ | 891 | ps.in_stmt = false; /* dont indent the {} */ | |
897 | if (!ps.block_init) | 892 | if (!ps.block_init) | |
898 | force_nl = true;/* force other stuff on same line as '{' onto | 893 | force_nl = true;/* force other stuff on same line as '{' onto | |
899 | * new line */ | 894 | * new line */ | |
900 | else if (ps.block_init_level <= 0) | 895 | else if (ps.block_init_level <= 0) | |
901 | ps.block_init_level = 1; | 896 | ps.block_init_level = 1; | |
902 | else | 897 | else | |
903 | ps.block_init_level++; | 898 | ps.block_init_level++; | |
904 | 899 | |||
905 | if (s_code != e_code && !ps.block_init) { | 900 | if (s_code != e_code && !ps.block_init) { | |
906 | if (!opt.btype_2) { | 901 | if (!opt.btype_2) { | |
907 | dump_line(); | 902 | dump_line(); | |
908 | ps.want_blank = false; | 903 | ps.want_blank = false; | |
909 | } | 904 | } else if (ps.in_parameter_declaration && !ps.in_or_st) { | |
910 | else if (ps.in_parameter_declaration && !ps.in_or_st) { | |||
911 | ps.i_l_follow = 0; | 905 | ps.i_l_follow = 0; | |
912 | if (opt.function_brace_split) { /* dump the line prior | 906 | if (opt.function_brace_split) { /* dump the line prior | |
913 | * to the brace ... */ | 907 | * to the brace ... */ | |
914 | dump_line(); | 908 | dump_line(); | |
915 | ps.want_blank = false; | 909 | ps.want_blank = false; | |
916 | } else /* add a space between the decl and brace */ | 910 | } else /* add a space between the decl and brace */ | |
917 | ps.want_blank = true; | 911 | ps.want_blank = true; | |
918 | } | 912 | } | |
919 | } | 913 | } | |
920 | if (ps.in_parameter_declaration) | 914 | if (ps.in_parameter_declaration) | |
921 | prefix_blankline_requested = 0; | 915 | prefix_blankline_requested = 0; | |
922 | 916 | |||
923 | if (ps.p_l_follow > 0) { /* check for preceding unbalanced | 917 | if (ps.p_l_follow > 0) { /* check for preceding unbalanced | |
924 | * parens */ | 918 | * parens */ | |
925 | diag(1, "Unbalanced parens"); | 919 | diag(1, "Unbalanced parens"); | |
926 | ps.p_l_follow = 0; | 920 | ps.p_l_follow = 0; | |
927 | if (sp_sw) { /* check for unclosed if, for, etc. */ | 921 | if (sp_sw) { /* check for unclosed if, for, etc. */ | |
928 | sp_sw = false; | 922 | sp_sw = false; | |
929 | parse(hd_type); | 923 | parse(hd_type); | |
930 | ps.ind_level = ps.i_l_follow; | 924 | ps.ind_level = ps.i_l_follow; | |
931 | } | 925 | } | |
932 | } | 926 | } | |
933 | if (s_code == e_code) | 927 | if (s_code == e_code) | |
934 | ps.ind_stmt = false; /* dont put extra indentation on line | 928 | ps.ind_stmt = false; /* dont put extra indentation on line | |
935 | * with '{' */ | 929 | * with '{' */ | |
936 | if (ps.in_decl && ps.in_or_st) { /* this is either a structure | 930 | if (ps.in_decl && ps.in_or_st) { /* this is either a structure | |
937 | * declaration or an init */ | 931 | * declaration or an init */ | |
938 | di_stack[ps.dec_nest] = dec_ind; | 932 | di_stack[ps.dec_nest] = dec_ind; | |
939 | if (++ps.dec_nest == nitems(di_stack)) { | 933 | if (++ps.dec_nest == nitems(di_stack)) { | |
940 | diag(0, "Reached internal limit of %zu struct levels", | 934 | diag(0, "Reached internal limit of %zu struct levels", | |
941 | nitems(di_stack)); | 935 | nitems(di_stack)); | |
942 | ps.dec_nest--; | 936 | ps.dec_nest--; | |
943 | } | 937 | } | |
944 | /* ? dec_ind = 0; */ | 938 | /* ? dec_ind = 0; */ | |
945 | } | 939 | } else { | |
946 | else { | |||
947 | ps.decl_on_line = false; /* we can't be in the middle of | 940 | ps.decl_on_line = false; /* we can't be in the middle of | |
948 | * a declaration, so don't do | 941 | * a declaration, so don't do | |
949 | * special indentation of | 942 | * special indentation of | |
950 | * comments */ | 943 | * comments */ | |
951 | if (opt.blanklines_after_declarations_at_proctop | 944 | if (opt.blanklines_after_declarations_at_proctop | |
952 | && ps.in_parameter_declaration) | 945 | && ps.in_parameter_declaration) | |
953 | postfix_blankline_requested = 1; | 946 | postfix_blankline_requested = 1; | |
954 | ps.in_parameter_declaration = 0; | 947 | ps.in_parameter_declaration = 0; | |
955 | ps.in_decl = false; | 948 | ps.in_decl = false; | |
956 | } | 949 | } | |
957 | dec_ind = 0; | 950 | dec_ind = 0; | |
958 | parse(lbrace); /* let parser know about this */ | 951 | parse(lbrace); /* let parser know about this */ | |
959 | if (ps.want_blank) /* put a blank before '{' if '{' is not at | 952 | if (ps.want_blank) /* put a blank before '{' if '{' is not at | |
960 | * start of line */ | 953 | * start of line */ | |
961 | *e_code++ = ' '; | 954 | *e_code++ = ' '; | |
962 | ps.want_blank = false; | 955 | ps.want_blank = false; | |
963 | *e_code++ = '{'; | 956 | *e_code++ = '{'; | |
964 | ps.just_saw_decl = 0; | 957 | ps.just_saw_decl = 0; | |
965 | break; | 958 | break; | |
966 | 959 | |||
967 | case rbrace: /* got a '}' */ | 960 | case rbrace: /* got a '}' */ | |
968 | if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be | 961 | if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be | |
969 | * omitted in | 962 | * omitted in | |
970 | * declarations */ | 963 | * declarations */ | |
971 | parse(semicolon); | 964 | parse(semicolon); | |
972 | if (ps.p_l_follow) {/* check for unclosed if, for, else. */ | 965 | if (ps.p_l_follow) {/* check for unclosed if, for, else. */ | |
973 | diag(1, "Unbalanced parens"); | 966 | diag(1, "Unbalanced parens"); | |
974 | ps.p_l_follow = 0; | 967 | ps.p_l_follow = 0; | |
975 | sp_sw = false; | 968 | sp_sw = false; | |
976 | } | 969 | } | |
977 | ps.just_saw_decl = 0; | 970 | ps.just_saw_decl = 0; | |
978 | ps.block_init_level--; | 971 | ps.block_init_level--; | |
979 | if (s_code != e_code && !ps.block_init) { /* '}' must be first on | 972 | if (s_code != e_code && !ps.block_init) { /* '}' must be first on | |
980 | * line */ | 973 | * line */ | |
981 | if (opt.verbose) | 974 | if (opt.verbose) | |
982 | diag(0, "Line broken"); | 975 | diag(0, "Line broken"); | |
983 | dump_line(); | 976 | dump_line(); | |
984 | } | 977 | } | |
985 | *e_code++ = '}'; | 978 | *e_code++ = '}'; | |
986 | ps.want_blank = true; | 979 | ps.want_blank = true; | |
987 | ps.in_stmt = ps.ind_stmt = false; | 980 | ps.in_stmt = ps.ind_stmt = false; | |
988 | if (ps.dec_nest > 0) { /* we are in multi-level structure | 981 | if (ps.dec_nest > 0) { /* we are in multi-level structure | |
989 | * declaration */ | 982 | * declaration */ | |
990 | dec_ind = di_stack[--ps.dec_nest]; | 983 | dec_ind = di_stack[--ps.dec_nest]; | |
991 | if (ps.dec_nest == 0 && !ps.in_parameter_declaration) | 984 | if (ps.dec_nest == 0 && !ps.in_parameter_declaration) | |
992 | ps.just_saw_decl = 2; | 985 | ps.just_saw_decl = 2; | |
993 | ps.in_decl = true; | 986 | ps.in_decl = true; | |
994 | } | 987 | } | |
995 | prefix_blankline_requested = 0; | 988 | prefix_blankline_requested = 0; | |
996 | parse(rbrace); /* let parser know about this */ | 989 | parse(rbrace); /* let parser know about this */ | |
997 | ps.search_brace = opt.cuddle_else | 990 | ps.search_brace = opt.cuddle_else | |
998 | && ps.p_stack[ps.tos] == if_expr_stmt | 991 | && ps.p_stack[ps.tos] == if_expr_stmt | |
999 | && ps.il[ps.tos] >= ps.ind_level; | 992 | && ps.il[ps.tos] >= ps.ind_level; | |
1000 | if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) | 993 | if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) | |
1001 | postfix_blankline_requested = 1; | 994 | postfix_blankline_requested = 1; | |
1002 | break; | 995 | break; | |
1003 | 996 | |||
1004 | case switch_expr: /* got keyword "switch" */ | 997 | case switch_expr: /* got keyword "switch" */ | |
1005 | sp_sw = true; | 998 | sp_sw = true; | |
1006 | hd_type = switch_expr; /* keep this for when we have seen the | 999 | hd_type = switch_expr; /* keep this for when we have seen the | |
1007 | * expression */ | 1000 | * expression */ | |
1008 | goto copy_id; /* go move the token into buffer */ | 1001 | goto copy_id; /* go move the token into buffer */ | |
1009 | 1002 | |||
1010 | case keyword_for_if_while: | 1003 | case keyword_for_if_while: | |
1011 | sp_sw = true; /* the interesting stuff is done after the | 1004 | sp_sw = true; /* the interesting stuff is done after the | |
1012 | * expression is scanned */ | 1005 | * expression is scanned */ | |
1013 | hd_type = (*token == 'i' ? if_expr : | 1006 | hd_type = (*token == 'i' ? if_expr : | |
1014 | (*token == 'w' ? while_expr : for_exprs)); | 1007 | (*token == 'w' ? while_expr : for_exprs)); | |
1015 | 1008 | |||
1016 | /* | 1009 | /* | |
1017 | * remember the type of header for later use by parser | 1010 | * remember the type of header for later use by parser | |
1018 | */ | 1011 | */ | |
1019 | goto copy_id; /* copy the token into line */ | 1012 | goto copy_id; /* copy the token into line */ | |
1020 | 1013 | |||
1021 | case keyword_do_else: | 1014 | case keyword_do_else: | |
1022 | ps.in_stmt = false; | 1015 | ps.in_stmt = false; | |
1023 | if (*token == 'e') { | 1016 | if (*token == 'e') { | |
1024 | if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { | 1017 | if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { | |
1025 | if (opt.verbose) | 1018 | if (opt.verbose) | |
1026 | diag(0, "Line broken"); | 1019 | diag(0, "Line broken"); | |
1027 | dump_line();/* make sure this starts a line */ | 1020 | dump_line();/* make sure this starts a line */ | |
1028 | ps.want_blank = false; | 1021 | ps.want_blank = false; | |
1029 | } | 1022 | } | |
1030 | force_nl = true;/* also, following stuff must go onto new line */ | 1023 | force_nl = true;/* also, following stuff must go onto new line */ | |
1031 | last_else = 1; | 1024 | last_else = 1; | |
1032 | parse(keyword_else); | 1025 | parse(keyword_else); | |
1033 | } | 1026 | } else { | |
1034 | else { | |||
1035 | if (e_code != s_code) { /* make sure this starts a line */ | 1027 | if (e_code != s_code) { /* make sure this starts a line */ | |
1036 | if (opt.verbose) | 1028 | if (opt.verbose) | |
1037 | diag(0, "Line broken"); | 1029 | diag(0, "Line broken"); | |
1038 | dump_line(); | 1030 | dump_line(); | |
1039 | ps.want_blank = false; | 1031 | ps.want_blank = false; | |
1040 | } | 1032 | } | |
1041 | force_nl = true;/* also, following stuff must go onto new line */ | 1033 | force_nl = true;/* also, following stuff must go onto new line */ | |
1042 | last_else = 0; | 1034 | last_else = 0; | |
1043 | parse(keyword_do); | 1035 | parse(keyword_do); | |
1044 | } | 1036 | } | |
1045 | goto copy_id; /* move the token into line */ | 1037 | goto copy_id; /* move the token into line */ | |
1046 | 1038 | |||
1047 | case type_def: | 1039 | case type_def: | |
1048 | case storage_class: | 1040 | case storage_class: | |
1049 | prefix_blankline_requested = 0; | 1041 | prefix_blankline_requested = 0; | |
1050 | goto copy_id; | 1042 | goto copy_id; | |
1051 | 1043 | |||
1052 | case keyword_struct_union_enum: | 1044 | case keyword_struct_union_enum: | |
1053 | if (ps.p_l_follow > 0) | 1045 | if (ps.p_l_follow > 0) | |
1054 | goto copy_id; | 1046 | goto copy_id; | |
1055 | /* FALLTHROUGH */ | 1047 | /* FALLTHROUGH */ | |
1056 | case decl: /* we have a declaration type (int, etc.) */ | 1048 | case decl: /* we have a declaration type (int, etc.) */ | |
1057 | parse(decl); /* let parser worry about indentation */ | 1049 | parse(decl); /* let parser worry about indentation */ | |
1058 | if (ps.last_token == rparen && ps.tos <= 1) { | 1050 | if (ps.last_token == rparen && ps.tos <= 1) { | |
1059 | if (s_code != e_code) { | 1051 | if (s_code != e_code) { | |
1060 | dump_line(); | 1052 | dump_line(); | |
1061 | ps.want_blank = 0; | 1053 | ps.want_blank = 0; | |
1062 | } | 1054 | } | |
1063 | } | 1055 | } | |
1064 | if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { | 1056 | if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { | |
1065 | ps.ind_level = ps.i_l_follow = 1; | 1057 | ps.ind_level = ps.i_l_follow = 1; | |
1066 | ps.ind_stmt = 0; | 1058 | ps.ind_stmt = 0; | |
1067 | } | 1059 | } | |
1068 | ps.in_or_st = true; /* this might be a structure or initialization | 1060 | ps.in_or_st = true; /* this might be a structure or initialization | |
1069 | * declaration */ | 1061 | * declaration */ | |
1070 | ps.in_decl = ps.decl_on_line = ps.last_token != type_def; | 1062 | ps.in_decl = ps.decl_on_line = ps.last_token != type_def; | |
1071 | if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) | 1063 | if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) | |
1072 | ps.just_saw_decl = 2; | 1064 | ps.just_saw_decl = 2; | |
1073 | prefix_blankline_requested = 0; | 1065 | prefix_blankline_requested = 0; | |
1074 | for (i = 0; token[i++];); /* get length of token */ | 1066 | for (i = 0; token[i++];); /* get length of token */ | |
1075 | 1067 | |||
1076 | if (ps.ind_level == 0 || ps.dec_nest > 0) { | 1068 | if (ps.ind_level == 0 || ps.dec_nest > 0) { | |
1077 | /* global variable or struct member in local variable */ | 1069 | /* global variable or struct member in local variable */ | |
1078 | dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; | 1070 | dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; | |
1079 | tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); | 1071 | tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); | |
1080 | } else { | 1072 | } else { | |
1081 | /* local variable */ | 1073 | /* local variable */ | |
1082 | dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; | 1074 | dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; | |
1083 | tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); | 1075 | tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); | |
1084 | } | 1076 | } | |
1085 | goto copy_id; | 1077 | goto copy_id; | |
1086 | 1078 | |||
1087 | case funcname: | 1079 | case funcname: | |
1088 | case ident: /* got an identifier or constant */ | 1080 | case ident: /* got an identifier or constant */ | |
1089 | if (ps.in_decl) { | 1081 | if (ps.in_decl) { | |
1090 | if (type_code == funcname) { | 1082 | if (type_code == funcname) { | |
1091 | ps.in_decl = false; | 1083 | ps.in_decl = false; | |
1092 | if (opt.procnames_start_line && s_code != e_code) { | 1084 | if (opt.procnames_start_line && s_code != e_code) { | |
1093 | *e_code = '\0'; | 1085 | *e_code = '\0'; | |
1094 | dump_line(); | 1086 | dump_line(); | |
1095 | } | 1087 | } else if (ps.want_blank) { | |
1096 | else if (ps.want_blank) { | |||
1097 | *e_code++ = ' '; | 1088 | *e_code++ = ' '; | |
1098 | } | 1089 | } | |
1099 | ps.want_blank = false; | 1090 | ps.want_blank = false; | |
1100 | } | 1091 | } else if (!ps.block_init && !ps.dumped_decl_indent && | |
1101 | else if (!ps.block_init && !ps.dumped_decl_indent && | |||
1102 | ps.paren_level == 0) { /* if we are in a declaration, we | 1092 | ps.paren_level == 0) { /* if we are in a declaration, we | |
1103 | * must indent identifier */ | 1093 | * must indent identifier */ | |
1104 | indent_declaration(dec_ind, tabs_to_var); | 1094 | indent_declaration(dec_ind, tabs_to_var); | |
1105 | ps.dumped_decl_indent = true; | 1095 | ps.dumped_decl_indent = true; | |
1106 | ps.want_blank = false; | 1096 | ps.want_blank = false; | |
1107 | } | 1097 | } | |
1108 | } | 1098 | } else if (sp_sw && ps.p_l_follow == 0) { | |
1109 | else if (sp_sw && ps.p_l_follow == 0) { | |||
1110 | sp_sw = false; | 1099 | sp_sw = false; | |
1111 | force_nl = true; | 1100 | force_nl = true; | |
1112 | ps.last_u_d = true; | 1101 | ps.last_u_d = true; | |
1113 | ps.in_stmt = false; | 1102 | ps.in_stmt = false; | |
1114 | parse(hd_type); | 1103 | parse(hd_type); | |
1115 | } | 1104 | } | |
1116 | copy_id: | 1105 | copy_id: | |
1117 | { | 1106 | { | |
1118 | int len = e_token - s_token; | 1107 | int len = e_token - s_token; | |
1119 | 1108 | |||
1120 | check_size_code(len + 1); | 1109 | check_size_code(len + 1); | |
1121 | if (ps.want_blank) | 1110 | if (ps.want_blank) | |
1122 | *e_code++ = ' '; | 1111 | *e_code++ = ' '; | |
1123 | memcpy(e_code, s_token, len); | 1112 | memcpy(e_code, s_token, len); | |
1124 | e_code += len; | 1113 | e_code += len; | |
1125 | } | 1114 | } | |
1126 | if (type_code != funcname) | 1115 | if (type_code != funcname) | |
1127 | ps.want_blank = true; | 1116 | ps.want_blank = true; | |
1128 | break; | 1117 | break; | |
1129 | 1118 | |||
1130 | case string_prefix: | 1119 | case string_prefix: | |
1131 | { | 1120 | { | |
1132 | int len = e_token - s_token; | 1121 | int len = e_token - s_token; | |
1133 | 1122 | |||
1134 | check_size_code(len + 1); | 1123 | check_size_code(len + 1); | |
1135 | if (ps.want_blank) | 1124 | if (ps.want_blank) | |
1136 | *e_code++ = ' '; | 1125 | *e_code++ = ' '; | |
1137 | memcpy(e_code, token, len); | 1126 | memcpy(e_code, token, len); | |
1138 | e_code += len; | 1127 | e_code += len; | |
1139 | } | 1128 | } | |
1140 | ps.want_blank = false; | 1129 | ps.want_blank = false; | |
1141 | break; | 1130 | break; | |
1142 | 1131 | |||
1143 | case period: /* treat a period kind of like a binary | 1132 | case period: /* treat a period kind of like a binary | |
1144 | * operation */ | 1133 | * operation */ | |
1145 | *e_code++ = '.'; /* move the period into line */ | 1134 | *e_code++ = '.'; /* move the period into line */ | |
1146 | ps.want_blank = false; /* dont put a blank after a period */ | 1135 | ps.want_blank = false; /* dont put a blank after a period */ | |
1147 | break; | 1136 | break; | |
1148 | 1137 | |||
1149 | case comma: | 1138 | case comma: | |
1150 | ps.want_blank = (s_code != e_code); /* only put blank after comma | 1139 | ps.want_blank = (s_code != e_code); /* only put blank after comma | |
1151 | * if comma does not start the | 1140 | * if comma does not start the | |
1152 | * line */ | 1141 | * line */ | |
1153 | if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && | 1142 | if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && | |
1154 | !ps.dumped_decl_indent && ps.paren_level == 0) { | 1143 | !ps.dumped_decl_indent && ps.paren_level == 0) { | |
1155 | /* indent leading commas and not the actual identifiers */ | 1144 | /* indent leading commas and not the actual identifiers */ | |
1156 | indent_declaration(dec_ind - 1, tabs_to_var); | 1145 | indent_declaration(dec_ind - 1, tabs_to_var); | |
1157 | ps.dumped_decl_indent = true; | 1146 | ps.dumped_decl_indent = true; | |
1158 | } | 1147 | } | |
1159 | *e_code++ = ','; | 1148 | *e_code++ = ','; | |
1160 | if (ps.p_l_follow == 0) { | 1149 | if (ps.p_l_follow == 0) { | |
1161 | if (ps.block_init_level <= 0) | 1150 | if (ps.block_init_level <= 0) | |
1162 | ps.block_init = 0; | 1151 | ps.block_init = 0; | |
1163 | if (break_comma && (!opt.leave_comma || | 1152 | if (break_comma && (!opt.leave_comma || | |
1164 | count_spaces_until(compute_code_target(), s_code, e_code) > | 1153 | count_spaces_until(compute_code_target(), s_code, e_code) > | |
1165 | opt.max_col - opt.tabsize)) | 1154 | opt.max_col - opt.tabsize)) | |
1166 | force_nl = true; | 1155 | force_nl = true; | |
1167 | } | 1156 | } | |
1168 | break; | 1157 | break; | |
1169 | 1158 | |||
1170 | case preprocessing: /* '#' */ | 1159 | case preprocessing: /* '#' */ | |
1171 | if ((s_com != e_com) || | 1160 | if ((s_com != e_com) || | |
1172 | (s_lab != e_lab) || | 1161 | (s_lab != e_lab) || | |
1173 | (s_code != e_code)) | 1162 | (s_code != e_code)) | |
1174 | dump_line(); | 1163 | dump_line(); | |
1175 | check_size_label(1); | 1164 | check_size_label(1); | |
1176 | *e_lab++ = '#'; /* move whole line to 'label' buffer */ | 1165 | *e_lab++ = '#'; /* move whole line to 'label' buffer */ | |
1177 | { | 1166 | { | |
1178 | int in_comment = 0; | 1167 | int in_comment = 0; | |
1179 | int com_start = 0; | 1168 | int com_start = 0; | |
1180 | char quote = 0; | 1169 | char quote = 0; | |
1181 | int com_end = 0; | 1170 | int com_end = 0; | |
1182 | 1171 | |||
1183 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | 1172 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | |
1184 | buf_ptr++; | 1173 | buf_ptr++; | |
1185 | if (buf_ptr >= buf_end) | 1174 | if (buf_ptr >= buf_end) | |
1186 | fill_buffer(); | 1175 | fill_buffer(); | |
1187 | } | 1176 | } | |
1188 | while (*buf_ptr != '\n' || (in_comment && !had_eof)) { | 1177 | while (*buf_ptr != '\n' || (in_comment && !had_eof)) { | |
1189 | check_size_label(2); | 1178 | check_size_label(2); | |
1190 | *e_lab = *buf_ptr++; | 1179 | *e_lab = *buf_ptr++; | |
1191 | if (buf_ptr >= buf_end) | 1180 | if (buf_ptr >= buf_end) | |
1192 | fill_buffer(); | 1181 | fill_buffer(); | |
1193 | switch (*e_lab++) { | 1182 | switch (*e_lab++) { | |
1194 | case '\\': | 1183 | case '\\': | |
1195 | if (!in_comment) { | 1184 | if (!in_comment) { | |
1196 | *e_lab++ = *buf_ptr++; | 1185 | *e_lab++ = *buf_ptr++; | |
1197 | if (buf_ptr >= buf_end) | 1186 | if (buf_ptr >= buf_end) | |
1198 | fill_buffer(); | 1187 | fill_buffer(); | |
1199 | } | 1188 | } | |
1200 | break; | 1189 | break; | |
1201 | case '/': | 1190 | case '/': | |
1202 | if (*buf_ptr == '*' && !in_comment && !quote) { | 1191 | if (*buf_ptr == '*' && !in_comment && !quote) { | |
1203 | in_comment = 1; | 1192 | in_comment = 1; | |
1204 | *e_lab++ = *buf_ptr++; | 1193 | *e_lab++ = *buf_ptr++; | |
1205 | com_start = e_lab - s_lab - 2; | 1194 | com_start = e_lab - s_lab - 2; | |
1206 | } | 1195 | } | |
1207 | break; | 1196 | break; | |
1208 | case '"': | 1197 | case '"': | |
1209 | if (quote == '"') | 1198 | if (quote == '"') | |
1210 | quote = 0; | 1199 | quote = 0; | |
1211 | break; | 1200 | break; | |
1212 | case '\'': | 1201 | case '\'': | |
1213 | if (quote == '\'') | 1202 | if (quote == '\'') | |
1214 | quote = 0; | 1203 | quote = 0; | |
1215 | break; | 1204 | break; | |
1216 | case '*': | 1205 | case '*': | |
1217 | if (*buf_ptr == '/' && in_comment) { | 1206 | if (*buf_ptr == '/' && in_comment) { | |
1218 | in_comment = 0; | 1207 | in_comment = 0; | |
1219 | *e_lab++ = *buf_ptr++; | 1208 | *e_lab++ = *buf_ptr++; | |
1220 | com_end = e_lab - s_lab; | 1209 | com_end = e_lab - s_lab; | |
1221 | } | 1210 | } | |
1222 | break; | 1211 | break; | |
1223 | } | 1212 | } | |
1224 | } | 1213 | } | |
1225 | 1214 | |||
1226 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | 1215 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | |
1227 | e_lab--; | 1216 | e_lab--; | |
1228 | if (e_lab - s_lab == com_end && bp_save == NULL) { | 1217 | if (e_lab - s_lab == com_end && bp_save == NULL) { | |
1229 | /* comment on preprocessor line */ | 1218 | /* comment on preprocessor line */ | |
1230 | if (sc_end == NULL) { /* if this is the first comment, | 1219 | if (sc_end == NULL) { /* if this is the first comment, | |
1231 | * we must set up the buffer */ | 1220 | * we must set up the buffer */ | |
1232 | save_com = sc_buf; | 1221 | save_com = sc_buf; | |
1233 | sc_end = &save_com[0]; | 1222 | sc_end = &save_com[0]; | |
1234 | } | 1223 | } else { | |
1235 | else { | |||
1236 | *sc_end++ = '\n'; /* add newline between | 1224 | *sc_end++ = '\n'; /* add newline between | |
1237 | * comments */ | 1225 | * comments */ | |
1238 | *sc_end++ = ' '; | 1226 | *sc_end++ = ' '; | |
1239 | --line_no; | 1227 | --line_no; | |
1240 | } | 1228 | } | |
1241 | if (sc_end - save_com + com_end - com_start > sc_size) | 1229 | if (sc_end - save_com + com_end - com_start > sc_size) | |
1242 | errx(1, "input too long"); | 1230 | errx(1, "input too long"); | |
1243 | memmove(sc_end, s_lab + com_start, com_end - com_start); | 1231 | memmove(sc_end, s_lab + com_start, com_end - com_start); | |
1244 | sc_end += com_end - com_start; | 1232 | sc_end += com_end - com_start; | |
1245 | e_lab = s_lab + com_start; | 1233 | e_lab = s_lab + com_start; | |
1246 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | 1234 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | |
1247 | e_lab--; | 1235 | e_lab--; | |
1248 | bp_save = buf_ptr; /* save current input buffer */ | 1236 | bp_save = buf_ptr; /* save current input buffer */ | |
1249 | be_save = buf_end; | 1237 | be_save = buf_end; | |
1250 | buf_ptr = save_com; /* fix so that subsequent calls to | 1238 | buf_ptr = save_com; /* fix so that subsequent calls to | |
1251 | * lexi will take tokens out of | 1239 | * lexi will take tokens out of | |
1252 | * save_com */ | 1240 | * save_com */ | |
1253 | *sc_end++ = ' '; /* add trailing blank, just in case */ | 1241 | *sc_end++ = ' '; /* add trailing blank, just in case */ | |
1254 | buf_end = sc_end; | 1242 | buf_end = sc_end; | |
1255 | sc_end = NULL; | 1243 | sc_end = NULL; | |
1256 | } | 1244 | } | |
1257 | check_size_label(1); | 1245 | check_size_label(1); | |
1258 | *e_lab = '\0'; /* null terminate line */ | 1246 | *e_lab = '\0'; /* null terminate line */ | |
1259 | ps.pcase = false; | 1247 | ps.pcase = false; | |
1260 | } | 1248 | } | |
1261 | 1249 | |||
1262 | if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ | 1250 | if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ | |
1263 | if ((size_t)ifdef_level < nitems(state_stack)) { | 1251 | if ((size_t)ifdef_level < nitems(state_stack)) { | |
1264 | match_state[ifdef_level].tos = -1; | 1252 | match_state[ifdef_level].tos = -1; | |
1265 | state_stack[ifdef_level++] = ps; | 1253 | state_stack[ifdef_level++] = ps; | |
1266 | } | 1254 | } else | |
1267 | else | |||
1268 | diag(1, "#if stack overflow"); | 1255 | diag(1, "#if stack overflow"); | |
1269 | } | 1256 | } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ | |
1270 | else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ | |||
1271 | if (ifdef_level <= 0) | 1257 | if (ifdef_level <= 0) | |
1272 | diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); | 1258 | diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); | |
1273 | else { | 1259 | else { | |
1274 | match_state[ifdef_level - 1] = ps; | 1260 | match_state[ifdef_level - 1] = ps; | |
1275 | ps = state_stack[ifdef_level - 1]; | 1261 | ps = state_stack[ifdef_level - 1]; | |
1276 | } | 1262 | } | |
1277 | } | 1263 | } else if (strncmp(s_lab, "#endif", 6) == 0) { | |
1278 | else if (strncmp(s_lab, "#endif", 6) == 0) { | |||
1279 | if (ifdef_level <= 0) | 1264 | if (ifdef_level <= 0) | |
1280 | diag(1, "Unmatched #endif"); | 1265 | diag(1, "Unmatched #endif"); | |
1281 | else | 1266 | else | |
1282 | ifdef_level--; | 1267 | ifdef_level--; | |
1283 | } else { | 1268 | } else { | |
1284 | static const struct directives { | 1269 | static const struct directives { | |
1285 | int size; | 1270 | int size; | |
1286 | const char *string; | 1271 | const char *string; | |
1287 | } recognized[] = { | 1272 | } recognized[] = { | |
1288 | {7, "include"}, | 1273 | {7, "include"}, | |
1289 | {6, "define"}, | 1274 | {6, "define"}, | |
1290 | {5, "undef"}, | 1275 | {5, "undef"}, | |
1291 | {4, "line"}, | 1276 | {4, "line"}, | |
1292 | {5, "error"}, | 1277 | {5, "error"}, | |
1293 | {6, "pragma"} | 1278 | {6, "pragma"} | |
1294 | }; | 1279 | }; | |
1295 | int d = nitems(recognized); | 1280 | int d = nitems(recognized); | |
1296 | while (--d >= 0) | 1281 | while (--d >= 0) | |
1297 | if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) | 1282 | if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) | |
1298 | break; | 1283 | break; | |
1299 | if (d < 0) { | 1284 | if (d < 0) { | |
1300 | diag(1, "Unrecognized cpp directive"); | 1285 | diag(1, "Unrecognized cpp directive"); | |
1301 | break; | 1286 | break; | |
1302 | } | 1287 | } | |
1303 | } | 1288 | } | |
1304 | if (opt.blanklines_around_conditional_compilation) { | 1289 | if (opt.blanklines_around_conditional_compilation) { | |
1305 | postfix_blankline_requested++; | 1290 | postfix_blankline_requested++; | |
1306 | n_real_blanklines = 0; | 1291 | n_real_blanklines = 0; | |
1307 | } | 1292 | } else { | |
1308 | else { | |||
1309 | postfix_blankline_requested = 0; | 1293 | postfix_blankline_requested = 0; | |
1310 | prefix_blankline_requested = 0; | 1294 | prefix_blankline_requested = 0; | |
1311 | } | 1295 | } | |
1312 | break; /* subsequent processing of the newline | 1296 | break; /* subsequent processing of the newline | |
1313 | * character will cause the line to be printed */ | 1297 | * character will cause the line to be printed */ | |
1314 | 1298 | |||
1315 | case comment: /* we have gotten a / followed by * this is a biggie */ | 1299 | case comment: /* we have gotten a / followed by * this is a biggie */ | |
1316 | pr_comment(); | 1300 | pr_comment(); | |
1317 | break; | 1301 | break; | |
1318 | 1302 | |||
1319 | default: | 1303 | default: | |
1320 | break; | 1304 | break; | |
1321 | } /* end of big switch stmt */ | 1305 | } /* end of big switch stmt */ | |
1322 | 1306 | |||
1323 | *e_code = '\0'; /* make sure code section is null terminated */ | 1307 | *e_code = '\0'; /* make sure code section is null terminated */ | |
1324 | if (type_code != comment && | 1308 | if (type_code != comment && | |
1325 | type_code != newline && | 1309 | type_code != newline && | |
1326 | type_code != preprocessing) | 1310 | type_code != preprocessing) | |
1327 | ps.last_token = type_code; | 1311 | ps.last_token = type_code; | |
1328 | } /* end of main while (1) loop */ | 1312 | } /* end of main while (1) loop */ | |
1329 | } | 1313 | } | |
1330 | 1314 | |||
1331 | /* | 1315 | /* | |
1332 | * copy input file to backup file if in_name is /blah/blah/blah/file, then | 1316 | * copy input file to backup file if in_name is /blah/blah/blah/file, then | |
1333 | * backup file will be ".Bfile" then make the backup file the input and | 1317 | * backup file will be ".Bfile" then make the backup file the input and | |
1334 | * original input file the output | 1318 | * original input file the output | |
1335 | */ | 1319 | */ | |
1336 | static void | 1320 | static void | |
1337 | bakcopy(void) | 1321 | bakcopy(void) | |
1338 | { | 1322 | { | |
1339 | int n, | 1323 | int n, | |
1340 | bakchn; | 1324 | bakchn; | |
1341 | char buff[8 * 1024]; | 1325 | char buff[8 * 1024]; | |
1342 | const char *p; | 1326 | const char *p; | |
1343 | 1327 | |||
1344 | /* construct file name .Bfile */ | 1328 | /* construct file name .Bfile */ | |
1345 | for (p = in_name; *p; p++); /* skip to end of string */ | 1329 | for (p = in_name; *p; p++); /* skip to end of string */ | |
1346 | while (p > in_name && *p != '/') /* find last '/' */ | 1330 | while (p > in_name && *p != '/') /* find last '/' */ | |
1347 | p--; | 1331 | p--; | |
1348 | if (*p == '/') | 1332 | if (*p == '/') | |
1349 | p++; | 1333 | p++; | |
1350 | sprintf(bakfile, "%s%s", p, simple_backup_suffix); | 1334 | sprintf(bakfile, "%s%s", p, simple_backup_suffix); | |
1351 | 1335 | |||
1352 | /* copy in_name to backup file */ | 1336 | /* copy in_name to backup file */ | |
1353 | bakchn = creat(bakfile, 0600); | 1337 | bakchn = creat(bakfile, 0600); | |
1354 | if (bakchn < 0) | 1338 | if (bakchn < 0) | |
1355 | err(1, "%s", bakfile); | 1339 | err(1, "%s", bakfile); | |
1356 | while ((n = read(fileno(input), buff, sizeof(buff))) > 0) | 1340 | while ((n = read(fileno(input), buff, sizeof(buff))) > 0) | |
1357 | if (write(bakchn, buff, n) != n) | 1341 | if (write(bakchn, buff, n) != n) | |
1358 | err(1, "%s", bakfile); | 1342 | err(1, "%s", bakfile); | |
1359 | if (n < 0) | 1343 | if (n < 0) | |
1360 | err(1, "%s", in_name); | 1344 | err(1, "%s", in_name); | |
1361 | close(bakchn); | 1345 | close(bakchn); | |
1362 | fclose(input); | 1346 | fclose(input); | |
1363 | 1347 | |||
1364 | /* re-open backup file as the input file */ | 1348 | /* re-open backup file as the input file */ | |
1365 | input = fopen(bakfile, "r"); | 1349 | input = fopen(bakfile, "r"); | |
1366 | if (input == NULL) | 1350 | if (input == NULL) | |
1367 | err(1, "%s", bakfile); | 1351 | err(1, "%s", bakfile); | |
1368 | /* now the original input file will be the output */ | 1352 | /* now the original input file will be the output */ | |
1369 | output = fopen(in_name, "w"); | 1353 | output = fopen(in_name, "w"); | |
1370 | if (output == NULL) { | 1354 | if (output == NULL) { | |
1371 | unlink(bakfile); | 1355 | unlink(bakfile); | |
1372 | err(1, "%s", in_name); | 1356 | err(1, "%s", in_name); | |
1373 | } | 1357 | } | |
1374 | } | 1358 | } | |
1375 | 1359 | |||
1376 | static void | 1360 | static void | |
1377 | indent_declaration(int cur_dec_ind, int tabs_to_var) | 1361 | indent_declaration(int cur_dec_ind, int tabs_to_var) | |
1378 | { | 1362 | { | |
1379 | int pos = e_code - s_code; | 1363 | int pos = e_code - s_code; | |
1380 | char *startpos = e_code; | 1364 | char *startpos = e_code; | |
1381 | 1365 | |||
1382 | /* | 1366 | /* | |
1383 | * get the tab math right for indentations that are not multiples of tabsize | 1367 | * get the tab math right for indentations that are not multiples of tabsize | |
1384 | */ | 1368 | */ | |
1385 | if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) { | 1369 | if ((ps.ind_level * opt.ind_size) % opt.tabsize != 0) { | |
1386 | pos += (ps.ind_level * opt.ind_size) % opt.tabsize; | 1370 | pos += (ps.ind_level * opt.ind_size) % opt.tabsize; | |
1387 | cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize; | 1371 | cur_dec_ind += (ps.ind_level * opt.ind_size) % opt.tabsize; | |
1388 | } | 1372 | } | |
1389 | if (tabs_to_var) { | 1373 | if (tabs_to_var) { | |
1390 | int tpos; | 1374 | int tpos; | |
1391 | 1375 | |||
1392 | check_size_code(cur_dec_ind / opt.tabsize); | 1376 | check_size_code(cur_dec_ind / opt.tabsize); | |
1393 | while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { | 1377 | while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { | |
1394 | *e_code++ = '\t'; | 1378 | *e_code++ = '\t'; | |
1395 | pos = tpos; | 1379 | pos = tpos; | |
1396 | } | 1380 | } | |
1397 | } | 1381 | } | |
1398 | check_size_code(cur_dec_ind - pos + 1); | 1382 | check_size_code(cur_dec_ind - pos + 1); | |
1399 | while (pos < cur_dec_ind) { | 1383 | while (pos < cur_dec_ind) { | |
1400 | *e_code++ = ' '; | 1384 | *e_code++ = ' '; | |
1401 | pos++; | 1385 | pos++; | |
1402 | } | 1386 | } | |
1403 | if (e_code == startpos && ps.want_blank) { | 1387 | if (e_code == startpos && ps.want_blank) { | |
1404 | *e_code++ = ' '; | 1388 | *e_code++ = ' '; | |
1405 | ps.want_blank = false; | 1389 | ps.want_blank = false; | |
1406 | } | 1390 | } | |
1407 | } | 1391 | } |
--- src/usr.bin/indent/io.c 2021/03/12 19:14:18 1.29
+++ src/usr.bin/indent/io.c 2021/03/12 23:10:18 1.30
@@ -1,545 +1,540 @@ | @@ -1,545 +1,540 @@ | |||
1 | /* $NetBSD: io.c,v 1.29 2021/03/12 19:14:18 rillig Exp $ */ | 1 | /* $NetBSD: io.c,v 1.30 2021/03/12 23:10:18 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1980, 1993 | 7 | * Copyright (c) 1980, 1993 | |
8 | * The Regents of the University of California. All rights reserved. | 8 | * The Regents of the University of California. All rights reserved. | |
9 | * All rights reserved. | 9 | * All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #if 0 | 40 | #if 0 | |
41 | #ifndef lint | 41 | #ifndef lint | |
42 | static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; | 42 | static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; | |
43 | #endif /* not lint */ | 43 | #endif /* not lint */ | |
44 | #endif | 44 | #endif | |
45 | 45 | |||
46 | #include <sys/cdefs.h> | 46 | #include <sys/cdefs.h> | |
47 | #ifndef lint | 47 | #ifndef lint | |
48 | #if defined(__NetBSD__) | 48 | #if defined(__NetBSD__) | |
49 | __RCSID("$NetBSD: io.c,v 1.29 2021/03/12 19:14:18 rillig Exp $"); | 49 | __RCSID("$NetBSD: io.c,v 1.30 2021/03/12 23:10:18 rillig Exp $"); | |
50 | #elif defined(__FreeBSD__) | 50 | #elif defined(__FreeBSD__) | |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $"); | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $"); | |
52 | #endif | 52 | #endif | |
53 | #endif | 53 | #endif | |
54 | 54 | |||
55 | #include <ctype.h> | 55 | #include <ctype.h> | |
56 | #include <err.h> | 56 | #include <err.h> | |
57 | #include <stdio.h> | 57 | #include <stdio.h> | |
58 | #include <stdlib.h> | 58 | #include <stdlib.h> | |
59 | #include <string.h> | 59 | #include <string.h> | |
60 | #include <stdarg.h> | 60 | #include <stdarg.h> | |
61 | 61 | |||
62 | #include "indent.h" | 62 | #include "indent.h" | |
63 | 63 | |||
64 | int comment_open; | 64 | int comment_open; | |
65 | static int paren_target; | 65 | static int paren_target; | |
66 | static int pad_output(int current, int target); | 66 | static int pad_output(int current, int target); | |
67 | 67 | |||
68 | static void | 68 | static void | |
69 | output_char(char ch) | 69 | output_char(char ch) | |
70 | { | 70 | { | |
71 | fputc(ch, output); | 71 | fputc(ch, output); | |
72 | } | 72 | } | |
73 | 73 | |||
74 | static void | 74 | static void | |
75 | output_range(const char *s, const char *e) | 75 | output_range(const char *s, const char *e) | |
76 | { | 76 | { | |
77 | fwrite(s, 1, (size_t)(e - s), output); | 77 | fwrite(s, 1, (size_t)(e - s), output); | |
78 | } | 78 | } | |
79 | 79 | |||
80 | static inline void | 80 | static inline void | |
81 | output_string(const char *s) | 81 | output_string(const char *s) | |
82 | { | 82 | { | |
83 | output_range(s, s + strlen(s)); | 83 | output_range(s, s + strlen(s)); | |
84 | } | 84 | } | |
85 | 85 | |||
86 | static void | 86 | static void | |
87 | output_int(int i) | 87 | output_int(int i) | |
88 | { | 88 | { | |
89 | fprintf(output, "%d", i); | 89 | fprintf(output, "%d", i); | |
90 | } | 90 | } | |
91 | 91 | |||
92 | /* | 92 | /* | |
93 | * dump_line is the routine that actually effects the printing of the new | 93 | * dump_line is the routine that actually effects the printing of the new | |
94 | * source. It prints the label section, followed by the code section with | 94 | * source. It prints the label section, followed by the code section with | |
95 | * the appropriate nesting level, followed by any comments. | 95 | * the appropriate nesting level, followed by any comments. | |
96 | */ | 96 | */ | |
97 | void | 97 | void | |
98 | dump_line(void) | 98 | dump_line(void) | |
99 | { | 99 | { | |
100 | int cur_col, target_col; | 100 | int cur_col, target_col; | |
101 | static int not_first_line; | 101 | static int not_first_line; | |
102 | 102 | |||
103 | if (ps.procname[0]) { | 103 | if (ps.procname[0]) { | |
104 | ps.ind_level = 0; | 104 | ps.ind_level = 0; | |
105 | ps.procname[0] = 0; | 105 | ps.procname[0] = 0; | |
106 | } | 106 | } | |
107 | ||||
107 | if (s_code == e_code && s_lab == e_lab && s_com == e_com) { | 108 | if (s_code == e_code && s_lab == e_lab && s_com == e_com) { | |
108 | if (suppress_blanklines > 0) | 109 | if (suppress_blanklines > 0) | |
109 | suppress_blanklines--; | 110 | suppress_blanklines--; | |
110 | else { | 111 | else { | |
111 | ps.bl_line = true; | 112 | ps.bl_line = true; | |
112 | n_real_blanklines++; | 113 | n_real_blanklines++; | |
113 | } | 114 | } | |
114 | } | 115 | } else if (!inhibit_formatting) { | |
115 | else if (!inhibit_formatting) { | |||
116 | suppress_blanklines = 0; | 116 | suppress_blanklines = 0; | |
117 | ps.bl_line = false; | 117 | ps.bl_line = false; | |
118 | if (prefix_blankline_requested && not_first_line) { | 118 | if (prefix_blankline_requested && not_first_line) { | |
119 | if (opt.swallow_optional_blanklines) { | 119 | if (opt.swallow_optional_blanklines) { | |
120 | if (n_real_blanklines == 1) | 120 | if (n_real_blanklines == 1) | |
121 | n_real_blanklines = 0; | 121 | n_real_blanklines = 0; | |
122 | } | 122 | } else { | |
123 | else { | |||
124 | if (n_real_blanklines == 0) | 123 | if (n_real_blanklines == 0) | |
125 | n_real_blanklines = 1; | 124 | n_real_blanklines = 1; | |
126 | } | 125 | } | |
127 | } | 126 | } | |
128 | while (--n_real_blanklines >= 0) | 127 | while (--n_real_blanklines >= 0) | |
129 | output_char('\n'); | 128 | output_char('\n'); | |
130 | n_real_blanklines = 0; | 129 | n_real_blanklines = 0; | |
131 | if (ps.ind_level == 0) | 130 | if (ps.ind_level == 0) | |
132 | ps.ind_stmt = 0; /* this is a class A kludge. dont do | 131 | ps.ind_stmt = 0; /* this is a class A kludge. dont do | |
133 | * additional statement indentation if we are | 132 | * additional statement indentation if we are | |
134 | * at bracket level 0 */ | 133 | * at bracket level 0 */ | |
135 | 134 | |||
136 | if (e_lab != s_lab || e_code != s_code) | 135 | if (e_lab != s_lab || e_code != s_code) | |
137 | ++code_lines; /* keep count of lines with code */ | 136 | ++code_lines; /* keep count of lines with code */ | |
138 | 137 | |||
139 | 138 | |||
140 | if (e_lab != s_lab) { /* print lab, if any */ | 139 | if (e_lab != s_lab) { /* print lab, if any */ | |
141 | if (comment_open) { | 140 | if (comment_open) { | |
142 | comment_open = 0; | 141 | comment_open = 0; | |
143 | output_string(".*/\n"); | 142 | output_string(".*/\n"); | |
144 | } | 143 | } | |
145 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | 144 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | |
146 | e_lab--; | 145 | e_lab--; | |
147 | *e_lab = '\0'; | 146 | *e_lab = '\0'; | |
148 | cur_col = pad_output(1, compute_label_target()); | 147 | cur_col = pad_output(1, compute_label_target()); | |
149 | if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 | 148 | if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 | |
150 | || strncmp(s_lab, "#endif", 6) == 0)) { | 149 | || strncmp(s_lab, "#endif", 6) == 0)) { | |
151 | char *s = s_lab; | 150 | char *s = s_lab; | |
152 | if (e_lab[-1] == '\n') e_lab--; | 151 | if (e_lab[-1] == '\n') e_lab--; | |
153 | do { | 152 | do { | |
154 | output_char(*s++); | 153 | output_char(*s++); | |
155 | } while (s < e_lab && 'a' <= *s && *s <= 'z'); | 154 | } while (s < e_lab && 'a' <= *s && *s <= 'z'); | |
156 | while ((*s == ' ' || *s == '\t') && s < e_lab) | 155 | while ((*s == ' ' || *s == '\t') && s < e_lab) | |
157 | s++; | 156 | s++; | |
158 | if (s < e_lab) { | 157 | if (s < e_lab) { | |
159 | if (s[0] == '/' && s[1] == '*') { | 158 | if (s[0] == '/' && s[1] == '*') { | |
160 | output_char('\t'); | 159 | output_char('\t'); | |
161 | output_range(s, e_lab); | 160 | output_range(s, e_lab); | |
162 | } else { | 161 | } else { | |
163 | output_string("\t/* "); | 162 | output_string("\t/* "); | |
164 | output_range(s, e_lab); | 163 | output_range(s, e_lab); | |
165 | output_string(" */"); | 164 | output_string(" */"); | |
166 | } | 165 | } | |
167 | } | 166 | } | |
168 | } else | 167 | } else | |
169 | output_range(s_lab, e_lab); | 168 | output_range(s_lab, e_lab); | |
170 | cur_col = count_spaces(cur_col, s_lab); | 169 | cur_col = count_spaces(cur_col, s_lab); | |
171 | } | 170 | } else | |
172 | else | |||
173 | cur_col = 1; /* there is no label section */ | 171 | cur_col = 1; /* there is no label section */ | |
174 | 172 | |||
175 | ps.pcase = false; | 173 | ps.pcase = false; | |
176 | 174 | |||
177 | if (s_code != e_code) { /* print code section, if any */ | 175 | if (s_code != e_code) { /* print code section, if any */ | |
178 | char *p; | 176 | char *p; | |
179 | 177 | |||
180 | if (comment_open) { | 178 | if (comment_open) { | |
181 | comment_open = 0; | 179 | comment_open = 0; | |
182 | output_string(".*/\n"); | 180 | output_string(".*/\n"); | |
183 | } | 181 | } | |
184 | target_col = compute_code_target(); | 182 | target_col = compute_code_target(); | |
185 | { | 183 | { | |
186 | int i; | 184 | int i; | |
187 | 185 | |||
188 | for (i = 0; i < ps.p_l_follow; i++) | 186 | for (i = 0; i < ps.p_l_follow; i++) | |
189 | if (ps.paren_indents[i] >= 0) | 187 | if (ps.paren_indents[i] >= 0) | |
190 | ps.paren_indents[i] = -(ps.paren_indents[i] + target_col); | 188 | ps.paren_indents[i] = -(ps.paren_indents[i] + target_col); | |
191 | } | 189 | } | |
192 | cur_col = pad_output(cur_col, target_col); | 190 | cur_col = pad_output(cur_col, target_col); | |
193 | for (p = s_code; p < e_code; p++) | 191 | for (p = s_code; p < e_code; p++) | |
194 | if (*p == (char) 0200) | 192 | if (*p == (char) 0200) | |
195 | output_int(target_col * 7); | 193 | output_int(target_col * 7); | |
196 | else | 194 | else | |
197 | output_char(*p); | 195 | output_char(*p); | |
198 | cur_col = count_spaces(cur_col, s_code); | 196 | cur_col = count_spaces(cur_col, s_code); | |
199 | } | 197 | } | |
200 | if (s_com != e_com) { /* print comment, if any */ | 198 | if (s_com != e_com) { /* print comment, if any */ | |
201 | int target = ps.com_col; | 199 | int target = ps.com_col; | |
202 | char *com_st = s_com; | 200 | char *com_st = s_com; | |
203 | 201 | |||
204 | target += ps.comment_delta; | 202 | target += ps.comment_delta; | |
205 | while (*com_st == '\t') /* consider original indentation in | 203 | while (*com_st == '\t') /* consider original indentation in | |
206 | * case this is a box comment */ | 204 | * case this is a box comment */ | |
207 | com_st++, target += opt.tabsize; | 205 | com_st++, target += opt.tabsize; | |
208 | while (target <= 0) | 206 | while (target <= 0) | |
209 | if (*com_st == ' ') | 207 | if (*com_st == ' ') | |
210 | target++, com_st++; | 208 | target++, com_st++; | |
211 | else if (*com_st == '\t') { | 209 | else if (*com_st == '\t') { | |
212 | target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1; | 210 | target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1; | |
213 | com_st++; | 211 | com_st++; | |
214 | } | 212 | } else | |
215 | else | |||
216 | target = 1; | 213 | target = 1; | |
217 | if (cur_col > target) { /* if comment can't fit on this line, | 214 | if (cur_col > target) { /* if comment can't fit on this line, | |
218 | * put it on next line */ | 215 | * put it on next line */ | |
219 | output_char('\n'); | 216 | output_char('\n'); | |
220 | cur_col = 1; | 217 | cur_col = 1; | |
221 | ++ps.out_lines; | 218 | ++ps.out_lines; | |
222 | } | 219 | } | |
223 | while (e_com > com_st && isspace((unsigned char)e_com[-1])) | 220 | while (e_com > com_st && isspace((unsigned char)e_com[-1])) | |
224 | e_com--; | 221 | e_com--; | |
225 | (void)pad_output(cur_col, target); | 222 | (void)pad_output(cur_col, target); | |
226 | output_range(com_st, e_com); | 223 | output_range(com_st, e_com); | |
227 | ps.comment_delta = ps.n_comment_delta; | 224 | ps.comment_delta = ps.n_comment_delta; | |
228 | ++ps.com_lines; /* count lines with comments */ | 225 | ++ps.com_lines; /* count lines with comments */ | |
229 | } | 226 | } | |
230 | if (ps.use_ff) | 227 | if (ps.use_ff) | |
231 | output_char('\014'); | 228 | output_char('\014'); | |
232 | else | 229 | else | |
233 | output_char('\n'); | 230 | output_char('\n'); | |
234 | ++ps.out_lines; | 231 | ++ps.out_lines; | |
235 | if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { | 232 | if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { | |
236 | prefix_blankline_requested = 1; | 233 | prefix_blankline_requested = 1; | |
237 | ps.just_saw_decl = 0; | 234 | ps.just_saw_decl = 0; | |
238 | } | 235 | } else | |
239 | else | |||
240 | prefix_blankline_requested = postfix_blankline_requested; | 236 | prefix_blankline_requested = postfix_blankline_requested; | |
241 | postfix_blankline_requested = 0; | 237 | postfix_blankline_requested = 0; | |
242 | } | 238 | } | |
243 | 239 | |||
244 | /* keep blank lines after '//' comments */ | 240 | /* keep blank lines after '//' comments */ | |
245 | if (e_com - s_com > 1 && s_com[1] == '/') | 241 | if (e_com - s_com > 1 && s_com[1] == '/') | |
246 | output_range(s_token, e_token); | 242 | output_range(s_token, e_token); | |
247 | 243 | |||
248 | ps.decl_on_line = ps.in_decl; /* if we are in the middle of a | 244 | ps.decl_on_line = ps.in_decl; /* if we are in the middle of a | |
249 | * declaration, remember that fact for | 245 | * declaration, remember that fact for | |
250 | * proper comment indentation */ | 246 | * proper comment indentation */ | |
251 | ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be | 247 | ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be | |
252 | * indented if we have not | 248 | * indented if we have not | |
253 | * completed this stmt and if | 249 | * completed this stmt and if | |
254 | * we are not in the middle of | 250 | * we are not in the middle of | |
255 | * a declaration */ | 251 | * a declaration */ | |
256 | ps.use_ff = false; | 252 | ps.use_ff = false; | |
257 | ps.dumped_decl_indent = 0; | 253 | ps.dumped_decl_indent = 0; | |
258 | *(e_lab = s_lab) = '\0'; /* reset buffers */ | 254 | *(e_lab = s_lab) = '\0'; /* reset buffers */ | |
259 | *(e_code = s_code) = '\0'; | 255 | *(e_code = s_code) = '\0'; | |
260 | *(e_com = s_com = combuf + 1) = '\0'; | 256 | *(e_com = s_com = combuf + 1) = '\0'; | |
261 | ps.ind_level = ps.i_l_follow; | 257 | ps.ind_level = ps.i_l_follow; | |
262 | ps.paren_level = ps.p_l_follow; | 258 | ps.paren_level = ps.p_l_follow; | |
263 | if (ps.paren_level > 0) | 259 | if (ps.paren_level > 0) | |
264 | paren_target = -ps.paren_indents[ps.paren_level - 1]; | 260 | paren_target = -ps.paren_indents[ps.paren_level - 1]; | |
265 | not_first_line = 1; | 261 | not_first_line = 1; | |
266 | } | 262 | } | |
267 | 263 | |||
268 | int | 264 | int | |
269 | compute_code_target(void) | 265 | compute_code_target(void) | |
270 | { | 266 | { | |
271 | int target_col = opt.ind_size * ps.ind_level + 1; | 267 | int target_col = opt.ind_size * ps.ind_level + 1; | |
272 | 268 | |||
273 | if (ps.paren_level) | 269 | if (ps.paren_level) { | |
274 | if (!opt.lineup_to_parens) | 270 | if (!opt.lineup_to_parens) | |
275 | target_col += opt.continuation_indent * | 271 | target_col += opt.continuation_indent * | |
276 | (2 * opt.continuation_indent == opt.ind_size ? 1 : ps.paren_level); | 272 | (2 * opt.continuation_indent == opt.ind_size ? 1 : ps.paren_level); | |
277 | else if (opt.lineup_to_parens_always) | 273 | else if (opt.lineup_to_parens_always) | |
278 | target_col = paren_target; | 274 | target_col = paren_target; | |
279 | else { | 275 | else { | |
280 | int w; | 276 | int w; | |
281 | int t = paren_target; | 277 | int t = paren_target; | |
282 | 278 | |||
283 | if ((w = count_spaces(t, s_code) - opt.max_col) > 0 | 279 | if ((w = count_spaces(t, s_code) - opt.max_col) > 0 | |
284 | && count_spaces(target_col, s_code) <= opt.max_col) { | 280 | && count_spaces(target_col, s_code) <= opt.max_col) { | |
285 | t -= w + 1; | 281 | t -= w + 1; | |
286 | if (t > target_col) | 282 | if (t > target_col) | |
287 | target_col = t; | 283 | target_col = t; | |
288 | } | 284 | } else | |
289 | else | |||
290 | target_col = t; | 285 | target_col = t; | |
291 | } | 286 | } | |
292 | else if (ps.ind_stmt) | 287 | } else if (ps.ind_stmt) | |
293 | target_col += opt.continuation_indent; | 288 | target_col += opt.continuation_indent; | |
294 | return target_col; | 289 | return target_col; | |
295 | } | 290 | } | |
296 | 291 | |||
297 | int | 292 | int | |
298 | compute_label_target(void) | 293 | compute_label_target(void) | |
299 | { | 294 | { | |
300 | return | 295 | return | |
301 | ps.pcase ? (int) (case_ind * opt.ind_size) + 1 | 296 | ps.pcase ? (int) (case_ind * opt.ind_size) + 1 | |
302 | : *s_lab == '#' ? 1 | 297 | : *s_lab == '#' ? 1 | |
303 | : opt.ind_size * (ps.ind_level - label_offset) + 1; | 298 | : opt.ind_size * (ps.ind_level - label_offset) + 1; | |
304 | } | 299 | } | |
305 | 300 | |||
306 | 301 | |||
307 | /* | 302 | /* | |
308 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | 303 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | |
309 | * | 304 | * | |
310 | * All rights reserved | 305 | * All rights reserved | |
311 | * | 306 | * | |
312 | * | 307 | * | |
313 | * NAME: fill_buffer | 308 | * NAME: fill_buffer | |
314 | * | 309 | * | |
315 | * FUNCTION: Reads one block of input into input_buffer | 310 | * FUNCTION: Reads one block of input into input_buffer | |
316 | * | 311 | * | |
317 | * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A | 312 | * HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A | |
318 | * Willcox of CAC Added check for switch back to partly full input | 313 | * Willcox of CAC Added check for switch back to partly full input | |
319 | * buffer from temporary buffer | 314 | * buffer from temporary buffer | |
320 | * | 315 | * | |
321 | */ | 316 | */ | |
322 | void | 317 | void | |
323 | fill_buffer(void) | 318 | fill_buffer(void) | |
324 | { /* this routine reads stuff from the input */ | 319 | { /* this routine reads stuff from the input */ | |
325 | char *p; | 320 | char *p; | |
326 | int i; | 321 | int i; | |
327 | FILE *f = input; | 322 | FILE *f = input; | |
328 | 323 | |||
329 | if (bp_save != NULL) { /* there is a partly filled input buffer left */ | 324 | if (bp_save != NULL) { /* there is a partly filled input buffer left */ | |
330 | buf_ptr = bp_save; /* do not read anything, just switch buffers */ | 325 | buf_ptr = bp_save; /* do not read anything, just switch buffers */ | |
331 | buf_end = be_save; | 326 | buf_end = be_save; | |
332 | bp_save = be_save = NULL; | 327 | bp_save = be_save = NULL; | |
333 | if (buf_ptr < buf_end) | 328 | if (buf_ptr < buf_end) | |
334 | return; /* only return if there is really something in | 329 | return; /* only return if there is really something in | |
335 | * this buffer */ | 330 | * this buffer */ | |
336 | } | 331 | } | |
337 | for (p = in_buffer;;) { | 332 | for (p = in_buffer;;) { | |
338 | if (p >= in_buffer_limit) { | 333 | if (p >= in_buffer_limit) { | |
339 | int size = (in_buffer_limit - in_buffer) * 2 + 10; | 334 | int size = (in_buffer_limit - in_buffer) * 2 + 10; | |
340 | int offset = p - in_buffer; | 335 | int offset = p - in_buffer; | |
341 | in_buffer = realloc(in_buffer, size); | 336 | in_buffer = realloc(in_buffer, size); | |
342 | if (in_buffer == NULL) | 337 | if (in_buffer == NULL) | |
343 | errx(1, "input line too long"); | 338 | errx(1, "input line too long"); | |
344 | p = in_buffer + offset; | 339 | p = in_buffer + offset; | |
345 | in_buffer_limit = in_buffer + size - 2; | 340 | in_buffer_limit = in_buffer + size - 2; | |
346 | } | 341 | } | |
347 | if ((i = getc(f)) == EOF) { | 342 | if ((i = getc(f)) == EOF) { | |
348 | *p++ = ' '; | 343 | *p++ = ' '; | |
349 | *p++ = '\n'; | 344 | *p++ = '\n'; | |
350 | had_eof = true; | 345 | had_eof = true; | |
351 | break; | 346 | break; | |
352 | } | 347 | } | |
353 | if (i != '\0') | 348 | if (i != '\0') | |
354 | *p++ = i; | 349 | *p++ = i; | |
355 | if (i == '\n') | 350 | if (i == '\n') | |
356 | break; | 351 | break; | |
357 | } | 352 | } | |
358 | buf_ptr = in_buffer; | 353 | buf_ptr = in_buffer; | |
359 | buf_end = p; | 354 | buf_end = p; | |
360 | if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { | 355 | if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { | |
361 | if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) | 356 | if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) | |
362 | fill_buffer(); /* flush indent error message */ | 357 | fill_buffer(); /* flush indent error message */ | |
363 | else { | 358 | else { | |
364 | int com = 0; | 359 | int com = 0; | |
365 | 360 | |||
366 | p = in_buffer; | 361 | p = in_buffer; | |
367 | while (*p == ' ' || *p == '\t') | 362 | while (*p == ' ' || *p == '\t') | |
368 | p++; | 363 | p++; | |
369 | if (*p == '/' && p[1] == '*') { | 364 | if (*p == '/' && p[1] == '*') { | |
370 | p += 2; | 365 | p += 2; | |
371 | while (*p == ' ' || *p == '\t') | 366 | while (*p == ' ' || *p == '\t') | |
372 | p++; | 367 | p++; | |
373 | if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E' | 368 | if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E' | |
374 | && p[4] == 'N' && p[5] == 'T') { | 369 | && p[4] == 'N' && p[5] == 'T') { | |
375 | p += 6; | 370 | p += 6; | |
376 | while (*p == ' ' || *p == '\t') | 371 | while (*p == ' ' || *p == '\t') | |
377 | p++; | 372 | p++; | |
378 | if (*p == '*') | 373 | if (*p == '*') | |
379 | com = 1; | 374 | com = 1; | |
380 | else if (*p == 'O') { | 375 | else if (*p == 'O') { | |
381 | if (*++p == 'N') | 376 | if (*++p == 'N') | |
382 | p++, com = 1; | 377 | p++, com = 1; | |
383 | else if (*p == 'F' && *++p == 'F') | 378 | else if (*p == 'F' && *++p == 'F') | |
384 | p++, com = 2; | 379 | p++, com = 2; | |
385 | } | 380 | } | |
386 | while (*p == ' ' || *p == '\t') | 381 | while (*p == ' ' || *p == '\t') | |
387 | p++; | 382 | p++; | |
388 | if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { | 383 | if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { | |
389 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | 384 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | |
390 | dump_line(); | 385 | dump_line(); | |
391 | if (!(inhibit_formatting = com - 1)) { | 386 | if (!(inhibit_formatting = com - 1)) { | |
392 | n_real_blanklines = 0; | 387 | n_real_blanklines = 0; | |
393 | postfix_blankline_requested = 0; | 388 | postfix_blankline_requested = 0; | |
394 | prefix_blankline_requested = 0; | 389 | prefix_blankline_requested = 0; | |
395 | suppress_blanklines = 1; | 390 | suppress_blanklines = 1; | |
396 | } | 391 | } | |
397 | } | 392 | } | |
398 | } | 393 | } | |
399 | } | 394 | } | |
400 | } | 395 | } | |
401 | } | 396 | } | |
402 | if (inhibit_formatting) { | 397 | if (inhibit_formatting) { | |
403 | p = in_buffer; | 398 | p = in_buffer; | |
404 | do { | 399 | do { | |
405 | output_char(*p); | 400 | output_char(*p); | |
406 | } while (*p++ != '\n'); | 401 | } while (*p++ != '\n'); | |
407 | } | 402 | } | |
408 | } | 403 | } | |
409 | 404 | |||
410 | /* | 405 | /* | |
411 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | 406 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | |
412 | * | 407 | * | |
413 | * All rights reserved | 408 | * All rights reserved | |
414 | * | 409 | * | |
415 | * | 410 | * | |
416 | * NAME: pad_output | 411 | * NAME: pad_output | |
417 | * | 412 | * | |
418 | * FUNCTION: Writes tabs and spaces to move the current column up to the desired | 413 | * FUNCTION: Writes tabs and spaces to move the current column up to the desired | |
419 | * position. | 414 | * position. | |
420 | * | 415 | * | |
421 | * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf. | 416 | * ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf. | |
422 | * | 417 | * | |
423 | * PARAMETERS: current integer The current column target | 418 | * PARAMETERS: current integer The current column target | |
424 | * nteger The desired column | 419 | * nteger The desired column | |
425 | * | 420 | * | |
426 | * RETURNS: Integer value of the new column. (If current >= target, no action is | 421 | * RETURNS: Integer value of the new column. (If current >= target, no action is | |
427 | * taken, and current is returned. | 422 | * taken, and current is returned. | |
428 | * | 423 | * | |
429 | * GLOBALS: None | 424 | * GLOBALS: None | |
430 | * | 425 | * | |
431 | * CALLS: write (sys) | 426 | * CALLS: write (sys) | |
432 | * | 427 | * | |
433 | * CALLED BY: dump_line | 428 | * CALLED BY: dump_line | |
434 | * | 429 | * | |
435 | * HISTORY: initial coding November 1976 D A Willcox of CAC | 430 | * HISTORY: initial coding November 1976 D A Willcox of CAC | |
436 | * | 431 | * | |
437 | */ | 432 | */ | |
438 | static int | 433 | static int | |
439 | pad_output(int current, int target) | 434 | pad_output(int current, int target) | |
440 | /* writes tabs and blanks (if necessary) to | 435 | /* writes tabs and blanks (if necessary) to | |
441 | * get the current output position up to the | 436 | * get the current output position up to the | |
442 | * target column */ | 437 | * target column */ | |
443 | /* current: the current column value */ | 438 | /* current: the current column value */ | |
444 | /* target: position we want it at */ | 439 | /* target: position we want it at */ | |
445 | { | 440 | { | |
446 | int curr; /* internal column pointer */ | 441 | int curr; /* internal column pointer */ | |
447 | 442 | |||
448 | if (current >= target) | 443 | if (current >= target) | |
449 | return current; /* line is already long enough */ | 444 | return current; /* line is already long enough */ | |
450 | curr = current; | 445 | curr = current; | |
451 | if (opt.use_tabs) { | 446 | if (opt.use_tabs) { | |
452 | int tcur; | 447 | int tcur; | |
453 | 448 | |||
454 | while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) { | 449 | while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) { | |
455 | output_char('\t'); | 450 | output_char('\t'); | |
456 | curr = tcur; | 451 | curr = tcur; | |
457 | } | 452 | } | |
458 | } | 453 | } | |
459 | while (curr++ < target) | 454 | while (curr++ < target) | |
460 | output_char(' '); /* pad with final blanks */ | 455 | output_char(' '); /* pad with final blanks */ | |
461 | 456 | |||
462 | return target; | 457 | return target; | |
463 | } | 458 | } | |
464 | 459 | |||
465 | /* | 460 | /* | |
466 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | 461 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | |
467 | * | 462 | * | |
468 | * All rights reserved | 463 | * All rights reserved | |
469 | * | 464 | * | |
470 | * | 465 | * | |
471 | * NAME: count_spaces | 466 | * NAME: count_spaces | |
472 | * | 467 | * | |
473 | * FUNCTION: Find out where printing of a given string will leave the current | 468 | * FUNCTION: Find out where printing of a given string will leave the current | |
474 | * character position on output. | 469 | * character position on output. | |
475 | * | 470 | * | |
476 | * ALGORITHM: Run thru input string and add appropriate values to current | 471 | * ALGORITHM: Run thru input string and add appropriate values to current | |
477 | * position. | 472 | * position. | |
478 | * | 473 | * | |
479 | * RETURNS: Integer value of position after printing "buffer" starting in column | 474 | * RETURNS: Integer value of position after printing "buffer" starting in column | |
480 | * "current". | 475 | * "current". | |
481 | * | 476 | * | |
482 | * HISTORY: initial coding November 1976 D A Willcox of CAC | 477 | * HISTORY: initial coding November 1976 D A Willcox of CAC | |
483 | * | 478 | * | |
484 | */ | 479 | */ | |
485 | int | 480 | int | |
486 | count_spaces_until(int cur, char *buffer, char *end) | 481 | count_spaces_until(int cur, char *buffer, char *end) | |
487 | /* | 482 | /* | |
488 | * this routine figures out where the character position will be after | 483 | * this routine figures out where the character position will be after | |
489 | * printing the text in buffer starting at column "current" | 484 | * printing the text in buffer starting at column "current" | |
490 | */ | 485 | */ | |
491 | { | 486 | { | |
492 | char *buf; /* used to look thru buffer */ | 487 | char *buf; /* used to look thru buffer */ | |
493 | 488 | |||
494 | for (buf = buffer; *buf != '\0' && buf != end; ++buf) { | 489 | for (buf = buffer; *buf != '\0' && buf != end; ++buf) { | |
495 | switch (*buf) { | 490 | switch (*buf) { | |
496 | 491 | |||
497 | case '\n': | 492 | case '\n': | |
498 | case 014: /* form feed */ | 493 | case 014: /* form feed */ | |
499 | cur = 1; | 494 | cur = 1; | |
500 | break; | 495 | break; | |
501 | 496 | |||
502 | case '\t': | 497 | case '\t': | |
503 | cur = opt.tabsize * (1 + (cur - 1) / opt.tabsize) + 1; | 498 | cur = opt.tabsize * (1 + (cur - 1) / opt.tabsize) + 1; | |
504 | break; | 499 | break; | |
505 | 500 | |||
506 | case 010: /* backspace */ | 501 | case 010: /* backspace */ | |
507 | --cur; | 502 | --cur; | |
508 | break; | 503 | break; | |
509 | 504 | |||
510 | default: | 505 | default: | |
511 | ++cur; | 506 | ++cur; | |
512 | break; | 507 | break; | |
513 | } /* end of switch */ | 508 | } /* end of switch */ | |
514 | } /* end of for loop */ | 509 | } /* end of for loop */ | |
515 | return cur; | 510 | return cur; | |
516 | } | 511 | } | |
517 | 512 | |||
518 | int | 513 | int | |
519 | count_spaces(int cur, char *buffer) | 514 | count_spaces(int cur, char *buffer) | |
520 | { | 515 | { | |
521 | return count_spaces_until(cur, buffer, NULL); | 516 | return count_spaces_until(cur, buffer, NULL); | |
522 | } | 517 | } | |
523 | 518 | |||
524 | void | 519 | void | |
525 | diag(int level, const char *msg, ...) | 520 | diag(int level, const char *msg, ...) | |
526 | { | 521 | { | |
527 | va_list ap; | 522 | va_list ap; | |
528 | const char *s, *e; | 523 | const char *s, *e; | |
529 | 524 | |||
530 | if (level) | 525 | if (level) | |
531 | found_err = 1; | 526 | found_err = 1; | |
532 | 527 | |||
533 | if (output == stdout) { | 528 | if (output == stdout) { | |
534 | s = "/**INDENT** "; | 529 | s = "/**INDENT** "; | |
535 | e = " */"; | 530 | e = " */"; | |
536 | } else { | 531 | } else { | |
537 | s = e = ""; | 532 | s = e = ""; | |
538 | } | 533 | } | |
539 | 534 | |||
540 | va_start(ap, msg); | 535 | va_start(ap, msg); | |
541 | fprintf(stderr, "%s%s@%d: ", s, level == 0 ? "Warning" : "Error", line_no); | 536 | fprintf(stderr, "%s%s@%d: ", s, level == 0 ? "Warning" : "Error", line_no); | |
542 | vfprintf(stderr, msg, ap); | 537 | vfprintf(stderr, msg, ap); | |
543 | fprintf(stderr, "%s\n", e); | 538 | fprintf(stderr, "%s\n", e); | |
544 | va_end(ap); | 539 | va_end(ap); | |
545 | } | 540 | } |
--- src/usr.bin/indent/lexi.c 2021/03/12 18:11:50 1.37
+++ src/usr.bin/indent/lexi.c 2021/03/12 23:10:18 1.38
@@ -1,733 +1,730 @@ | @@ -1,733 +1,730 @@ | |||
1 | /* $NetBSD: lexi.c,v 1.37 2021/03/12 18:11:50 rillig Exp $ */ | 1 | /* $NetBSD: lexi.c,v 1.38 2021/03/12 23:10:18 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1980, 1993 | 7 | * Copyright (c) 1980, 1993 | |
8 | * The Regents of the University of California. All rights reserved. | 8 | * The Regents of the University of California. All rights reserved. | |
9 | * All rights reserved. | 9 | * All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #if 0 | 40 | #if 0 | |
41 | #ifndef lint | 41 | #ifndef lint | |
42 | static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93"; | 42 | static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93"; | |
43 | #endif /* not lint */ | 43 | #endif /* not lint */ | |
44 | #endif | 44 | #endif | |
45 | 45 | |||
46 | #include <sys/cdefs.h> | 46 | #include <sys/cdefs.h> | |
47 | #ifndef lint | 47 | #ifndef lint | |
48 | #if defined(__NetBSD__) | 48 | #if defined(__NetBSD__) | |
49 | __RCSID("$NetBSD: lexi.c,v 1.37 2021/03/12 18:11:50 rillig Exp $"); | 49 | __RCSID("$NetBSD: lexi.c,v 1.38 2021/03/12 23:10:18 rillig Exp $"); | |
50 | #elif defined(__FreeBSD__) | 50 | #elif defined(__FreeBSD__) | |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/lexi.c 337862 2018-08-15 18:19:45Z pstef $"); | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/lexi.c 337862 2018-08-15 18:19:45Z pstef $"); | |
52 | #endif | 52 | #endif | |
53 | #endif | 53 | #endif | |
54 | 54 | |||
55 | /* | 55 | /* | |
56 | * Here we have the token scanner for indent. It scans off one token and puts | 56 | * Here we have the token scanner for indent. It scans off one token and puts | |
57 | * it in the global variable "token". It returns a code, indicating the type | 57 | * it in the global variable "token". It returns a code, indicating the type | |
58 | * of token scanned. | 58 | * of token scanned. | |
59 | */ | 59 | */ | |
60 | 60 | |||
61 | #include <assert.h> | 61 | #include <assert.h> | |
62 | #include <err.h> | 62 | #include <err.h> | |
63 | #include <stdio.h> | 63 | #include <stdio.h> | |
64 | #include <ctype.h> | 64 | #include <ctype.h> | |
65 | #include <stdlib.h> | 65 | #include <stdlib.h> | |
66 | #include <string.h> | 66 | #include <string.h> | |
67 | #include <sys/param.h> | 67 | #include <sys/param.h> | |
68 | 68 | |||
69 | #include "indent.h" | 69 | #include "indent.h" | |
70 | 70 | |||
71 | struct templ { | 71 | struct templ { | |
72 | const char *rwd; | 72 | const char *rwd; | |
73 | enum rwcode rwcode; | 73 | enum rwcode rwcode; | |
74 | }; | 74 | }; | |
75 | 75 | |||
76 | /* | 76 | /* | |
77 | * This table has to be sorted alphabetically, because it'll be used in binary | 77 | * This table has to be sorted alphabetically, because it'll be used in binary | |
78 | * search. | 78 | * search. | |
79 | */ | 79 | */ | |
80 | const struct templ specials[] = | 80 | const struct templ specials[] = | |
81 | { | 81 | { | |
82 | {"_Bool", rw_type}, | 82 | {"_Bool", rw_type}, | |
83 | {"_Complex", rw_type}, | 83 | {"_Complex", rw_type}, | |
84 | {"_Imaginary", rw_type}, | 84 | {"_Imaginary", rw_type}, | |
85 | {"auto", rw_storage_class}, | 85 | {"auto", rw_storage_class}, | |
86 | {"bool", rw_type}, | 86 | {"bool", rw_type}, | |
87 | {"break", rw_jump}, | 87 | {"break", rw_jump}, | |
88 | {"case", rw_case_or_default}, | 88 | {"case", rw_case_or_default}, | |
89 | {"char", rw_type}, | 89 | {"char", rw_type}, | |
90 | {"complex", rw_type}, | 90 | {"complex", rw_type}, | |
91 | {"const", rw_type}, | 91 | {"const", rw_type}, | |
92 | {"continue", rw_jump}, | 92 | {"continue", rw_jump}, | |
93 | {"default", rw_case_or_default}, | 93 | {"default", rw_case_or_default}, | |
94 | {"do", rw_do_or_else}, | 94 | {"do", rw_do_or_else}, | |
95 | {"double", rw_type}, | 95 | {"double", rw_type}, | |
96 | {"else", rw_do_or_else}, | 96 | {"else", rw_do_or_else}, | |
97 | {"enum", rw_struct_or_union_or_enum}, | 97 | {"enum", rw_struct_or_union_or_enum}, | |
98 | {"extern", rw_storage_class}, | 98 | {"extern", rw_storage_class}, | |
99 | {"float", rw_type}, | 99 | {"float", rw_type}, | |
100 | {"for", rw_for_or_if_or_while}, | 100 | {"for", rw_for_or_if_or_while}, | |
101 | {"global", rw_type}, | 101 | {"global", rw_type}, | |
102 | {"goto", rw_jump}, | 102 | {"goto", rw_jump}, | |
103 | {"if", rw_for_or_if_or_while}, | 103 | {"if", rw_for_or_if_or_while}, | |
104 | {"imaginary", rw_type}, | 104 | {"imaginary", rw_type}, | |
105 | {"inline", rw_inline_or_restrict}, | 105 | {"inline", rw_inline_or_restrict}, | |
106 | {"int", rw_type}, | 106 | {"int", rw_type}, | |
107 | {"long", rw_type}, | 107 | {"long", rw_type}, | |
108 | {"offsetof", rw_offsetof}, | 108 | {"offsetof", rw_offsetof}, | |
109 | {"register", rw_storage_class}, | 109 | {"register", rw_storage_class}, | |
110 | {"restrict", rw_inline_or_restrict}, | 110 | {"restrict", rw_inline_or_restrict}, | |
111 | {"return", rw_jump}, | 111 | {"return", rw_jump}, | |
112 | {"short", rw_type}, | 112 | {"short", rw_type}, | |
113 | {"signed", rw_type}, | 113 | {"signed", rw_type}, | |
114 | {"sizeof", rw_sizeof}, | 114 | {"sizeof", rw_sizeof}, | |
115 | {"static", rw_storage_class}, | 115 | {"static", rw_storage_class}, | |
116 | {"struct", rw_struct_or_union_or_enum}, | 116 | {"struct", rw_struct_or_union_or_enum}, | |
117 | {"switch", rw_switch}, | 117 | {"switch", rw_switch}, | |
118 | {"typedef", rw_typedef}, | 118 | {"typedef", rw_typedef}, | |
119 | {"union", rw_struct_or_union_or_enum}, | 119 | {"union", rw_struct_or_union_or_enum}, | |
120 | {"unsigned", rw_type}, | 120 | {"unsigned", rw_type}, | |
121 | {"void", rw_type}, | 121 | {"void", rw_type}, | |
122 | {"volatile", rw_type}, | 122 | {"volatile", rw_type}, | |
123 | {"while", rw_for_or_if_or_while} | 123 | {"while", rw_for_or_if_or_while} | |
124 | }; | 124 | }; | |
125 | 125 | |||
126 | const char **typenames; | 126 | const char **typenames; | |
127 | int typename_count; | 127 | int typename_count; | |
128 | int typename_top = -1; | 128 | int typename_top = -1; | |
129 | 129 | |||
130 | /* | 130 | /* | |
131 | * The transition table below was rewritten by hand from lx's output, given | 131 | * The transition table below was rewritten by hand from lx's output, given | |
132 | * the following definitions. lx is Katherine Flavel's lexer generator. | 132 | * the following definitions. lx is Katherine Flavel's lexer generator. | |
133 | * | 133 | * | |
134 | * O = /[0-7]/; D = /[0-9]/; NZ = /[1-9]/; | 134 | * O = /[0-7]/; D = /[0-9]/; NZ = /[1-9]/; | |
135 | * H = /[a-f0-9]/i; B = /[0-1]/; HP = /0x/i; | 135 | * H = /[a-f0-9]/i; B = /[0-1]/; HP = /0x/i; | |
136 | * BP = /0b/i; E = /e[+\-]?/i D+; P = /p[+\-]?/i D+; | 136 | * BP = /0b/i; E = /e[+\-]?/i D+; P = /p[+\-]?/i D+; | |
137 | * FS = /[fl]/i; IS = /u/i /(l|L|ll|LL)/? | /(l|L|ll|LL)/ /u/i?; | 137 | * FS = /[fl]/i; IS = /u/i /(l|L|ll|LL)/? | /(l|L|ll|LL)/ /u/i?; | |
138 | * | 138 | * | |
139 | * D+ E FS? -> $float; | 139 | * D+ E FS? -> $float; | |
140 | * D* "." D+ E? FS? -> $float; | 140 | * D* "." D+ E? FS? -> $float; | |
141 | * D+ "." E? FS? -> $float; HP H+ IS? -> $int; | 141 | * D+ "." E? FS? -> $float; HP H+ IS? -> $int; | |
142 | * HP H+ P FS? -> $float; NZ D* IS? -> $int; | 142 | * HP H+ P FS? -> $float; NZ D* IS? -> $int; | |
143 | * HP H* "." H+ P FS? -> $float; "0" O* IS? -> $int; | 143 | * HP H* "." H+ P FS? -> $float; "0" O* IS? -> $int; | |
144 | * HP H+ "." P FS -> $float; BP B+ IS? -> $int; | 144 | * HP H+ "." P FS -> $float; BP B+ IS? -> $int; | |
145 | */ | 145 | */ | |
146 | static char const *table[] = { | 146 | static char const *table[] = { | |
147 | /* examples: | 147 | /* examples: | |
148 | 00 | 148 | 00 | |
149 | s 0xx | 149 | s 0xx | |
150 | t 00xaa | 150 | t 00xaa | |
151 | a 11 101100xxa.. | 151 | a 11 101100xxa.. | |
152 | r 11ee0001101lbuuxx.a.pp | 152 | r 11ee0001101lbuuxx.a.pp | |
153 | t.01.e+008bLuxll0Ll.aa.p+0 | 153 | t.01.e+008bLuxll0Ll.aa.p+0 | |
154 | states: ABCDEFGHIJKLMNOPQRSTUVWXYZ */ | 154 | states: ABCDEFGHIJKLMNOPQRSTUVWXYZ */ | |
155 | ['0'] = "CEIDEHHHIJQ U Q VUVVZZZ", | 155 | ['0'] = "CEIDEHHHIJQ U Q VUVVZZZ", | |
156 | ['1'] = "DEIDEHHHIJQ U Q VUVVZZZ", | 156 | ['1'] = "DEIDEHHHIJQ U Q VUVVZZZ", | |
157 | ['7'] = "DEIDEHHHIJ U VUVVZZZ", | 157 | ['7'] = "DEIDEHHHIJ U VUVVZZZ", | |
158 | ['9'] = "DEJDEHHHJJ U VUVVZZZ", | 158 | ['9'] = "DEJDEHHHJJ U VUVVZZZ", | |
159 | ['a'] = " U VUVV ", | 159 | ['a'] = " U VUVV ", | |
160 | ['b'] = " K U VUVV ", | 160 | ['b'] = " K U VUVV ", | |
161 | ['e'] = " FFF FF U VUVV ", | 161 | ['e'] = " FFF FF U VUVV ", | |
162 | ['f'] = " f f U VUVV f", | 162 | ['f'] = " f f U VUVV f", | |
163 | ['u'] = " MM M i iiM M ", | 163 | ['u'] = " MM M i iiM M ", | |
164 | ['x'] = " N ", | 164 | ['x'] = " N ", | |
165 | ['p'] = " FFX ", | 165 | ['p'] = " FFX ", | |
166 | ['L'] = " LLf fL PR Li L f", | 166 | ['L'] = " LLf fL PR Li L f", | |
167 | ['l'] = " OOf fO S P O i O f", | 167 | ['l'] = " OOf fO S P O i O f", | |
168 | ['+'] = " G Y ", | 168 | ['+'] = " G Y ", | |
169 | ['.'] = "B EE EE T W ", | 169 | ['.'] = "B EE EE T W ", | |
170 | /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */ | 170 | /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */ | |
171 | [0] = "uuiifuufiuuiiuiiiiiuiuuuuu", | 171 | [0] = "uuiifuufiuuiiuiiiiiuiuuuuu", | |
172 | }; | 172 | }; | |
173 | 173 | |||
174 | /* Initialize constant transition table */ | 174 | /* Initialize constant transition table */ | |
175 | void | 175 | void | |
176 | init_constant_tt(void) | 176 | init_constant_tt(void) | |
177 | { | 177 | { | |
178 | table['-'] = table['+']; | 178 | table['-'] = table['+']; | |
179 | table['8'] = table['9']; | 179 | table['8'] = table['9']; | |
180 | table['2'] = table['3'] = table['4'] = table['5'] = table['6'] = table['7']; | 180 | table['2'] = table['3'] = table['4'] = table['5'] = table['6'] = table['7']; | |
181 | table['A'] = table['C'] = table['D'] = table['c'] = table['d'] = table['a']; | 181 | table['A'] = table['C'] = table['D'] = table['c'] = table['d'] = table['a']; | |
182 | table['B'] = table['b']; | 182 | table['B'] = table['b']; | |
183 | table['E'] = table['e']; | 183 | table['E'] = table['e']; | |
184 | table['U'] = table['u']; | 184 | table['U'] = table['u']; | |
185 | table['X'] = table['x']; | 185 | table['X'] = table['x']; | |
186 | table['P'] = table['p']; | 186 | table['P'] = table['p']; | |
187 | table['F'] = table['f']; | 187 | table['F'] = table['f']; | |
188 | } | 188 | } | |
189 | 189 | |||
190 | static char | 190 | static char | |
191 | inbuf_peek(void) | 191 | inbuf_peek(void) | |
192 | { | 192 | { | |
193 | return *buf_ptr; | 193 | return *buf_ptr; | |
194 | } | 194 | } | |
195 | 195 | |||
196 | static void | 196 | static void | |
197 | inbuf_skip(void) | 197 | inbuf_skip(void) | |
198 | { | 198 | { | |
199 | buf_ptr++; | 199 | buf_ptr++; | |
200 | if (buf_ptr >= buf_end) | 200 | if (buf_ptr >= buf_end) | |
201 | fill_buffer(); | 201 | fill_buffer(); | |
202 | } | 202 | } | |
203 | 203 | |||
204 | static char | 204 | static char | |
205 | inbuf_next(void) | 205 | inbuf_next(void) | |
206 | { | 206 | { | |
207 | char ch = inbuf_peek(); | 207 | char ch = inbuf_peek(); | |
208 | inbuf_skip(); | 208 | inbuf_skip(); | |
209 | return ch; | 209 | return ch; | |
210 | } | 210 | } | |
211 | 211 | |||
212 | static void | 212 | static void | |
213 | check_size_token(size_t desired_size) | 213 | check_size_token(size_t desired_size) | |
214 | { | 214 | { | |
215 | if (e_token + (desired_size) < l_token) | 215 | if (e_token + (desired_size) < l_token) | |
216 | return; | 216 | return; | |
217 | 217 | |||
218 | size_t nsize = l_token - s_token + 400 + desired_size; | 218 | size_t nsize = l_token - s_token + 400 + desired_size; | |
219 | size_t token_len = e_token - s_token; | 219 | size_t token_len = e_token - s_token; | |
220 | tokenbuf = realloc(tokenbuf, nsize); | 220 | tokenbuf = realloc(tokenbuf, nsize); | |
221 | if (tokenbuf == NULL) | 221 | if (tokenbuf == NULL) | |
222 | err(1, NULL); | 222 | err(1, NULL); | |
223 | e_token = tokenbuf + token_len + 1; | 223 | e_token = tokenbuf + token_len + 1; | |
224 | l_token = tokenbuf + nsize - 5; | 224 | l_token = tokenbuf + nsize - 5; | |
225 | s_token = tokenbuf + 1; | 225 | s_token = tokenbuf + 1; | |
226 | } | 226 | } | |
227 | 227 | |||
228 | static int | 228 | static int | |
229 | compare_templ_array(const void *key, const void *elem) | 229 | compare_templ_array(const void *key, const void *elem) | |
230 | { | 230 | { | |
231 | return strcmp(key, ((const struct templ *)elem)->rwd); | 231 | return strcmp(key, ((const struct templ *)elem)->rwd); | |
232 | } | 232 | } | |
233 | 233 | |||
234 | static int | 234 | static int | |
235 | compare_string_array(const void *key, const void *elem) | 235 | compare_string_array(const void *key, const void *elem) | |
236 | { | 236 | { | |
237 | return strcmp(key, *((const char *const *)elem)); | 237 | return strcmp(key, *((const char *const *)elem)); | |
238 | } | 238 | } | |
239 | 239 | |||
240 | #ifdef debug | 240 | #ifdef debug | |
241 | const char * | 241 | const char * | |
242 | token_type_name(token_type tk) | 242 | token_type_name(token_type tk) | |
243 | { | 243 | { | |
244 | static const char *const name[] = { | 244 | static const char *const name[] = { | |
245 | "end_of_file", "newline", "lparen", "rparen", "unary_op", | 245 | "end_of_file", "newline", "lparen", "rparen", "unary_op", | |
246 | "binary_op", "postfix_op", "question", "case_label", "colon", | 246 | "binary_op", "postfix_op", "question", "case_label", "colon", | |
247 | "semicolon", "lbrace", "rbrace", "ident", "comma", | 247 | "semicolon", "lbrace", "rbrace", "ident", "comma", | |
248 | "comment", "switch_expr", "preprocessing", "form_feed", "decl", | 248 | "comment", "switch_expr", "preprocessing", "form_feed", "decl", | |
249 | "keyword_for_if_while", "keyword_do_else", | 249 | "keyword_for_if_while", "keyword_do_else", | |
250 | "if_expr", "while_expr", "for_exprs", | 250 | "if_expr", "while_expr", "for_exprs", | |
251 | "stmt", "stmt_list", "keyword_else", "keyword_do", "do_stmt", | 251 | "stmt", "stmt_list", "keyword_else", "keyword_do", "do_stmt", | |
252 | "if_expr_stmt", "if_expr_stmt_else", "period", "string_prefix", | 252 | "if_expr_stmt", "if_expr_stmt_else", "period", "string_prefix", | |
253 | "storage_class", "funcname", "type_def", "keyword_struct_union_enum" | 253 | "storage_class", "funcname", "type_def", "keyword_struct_union_enum" | |
254 | }; | 254 | }; | |
255 | 255 | |||
256 | assert(0 <= tk && tk < sizeof name / sizeof name[0]); | 256 | assert(0 <= tk && tk < sizeof name / sizeof name[0]); | |
257 | 257 | |||
258 | return name[tk]; | 258 | return name[tk]; | |
259 | } | 259 | } | |
260 | 260 | |||
261 | static void | 261 | static void | |
262 | print_buf(const char *name, const char *s, const char *e) | 262 | print_buf(const char *name, const char *s, const char *e) | |
263 | { | 263 | { | |
264 | if (s == e) | 264 | if (s == e) | |
265 | return; | 265 | return; | |
266 | 266 | |||
267 | printf(" %s \"", name); | 267 | printf(" %s \"", name); | |
268 | for (const char *p = s; p < e; p++) { | 268 | for (const char *p = s; p < e; p++) { | |
269 | if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') | 269 | if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') | |
270 | printf("%c", *p); | 270 | printf("%c", *p); | |
271 | else if (*p == '\n') | 271 | else if (*p == '\n') | |
272 | printf("\\n"); | 272 | printf("\\n"); | |
273 | else if (*p == '\t') | 273 | else if (*p == '\t') | |
274 | printf("\\t"); | 274 | printf("\\t"); | |
275 | else | 275 | else | |
276 | printf("\\x%02x", *p); | 276 | printf("\\x%02x", *p); | |
277 | } | 277 | } | |
278 | printf("\""); | 278 | printf("\""); | |
279 | } | 279 | } | |
280 | 280 | |||
281 | static token_type | 281 | static token_type | |
282 | lexi_end(token_type code) | 282 | lexi_end(token_type code) | |
283 | { | 283 | { | |
284 | printf("in line %d, lexi returns '%s'", line_no, token_type_name(code)); | 284 | printf("in line %d, lexi returns '%s'", line_no, token_type_name(code)); | |
285 | print_buf("token", s_token, e_token); | 285 | print_buf("token", s_token, e_token); | |
286 | print_buf("label", s_lab, e_lab); | 286 | print_buf("label", s_lab, e_lab); | |
287 | print_buf("code", s_code, e_code); | 287 | print_buf("code", s_code, e_code); | |
288 | print_buf("comment", s_com, e_com); | 288 | print_buf("comment", s_com, e_com); | |
289 | printf("\n"); | 289 | printf("\n"); | |
290 | 290 | |||
291 | return code; | 291 | return code; | |
292 | } | 292 | } | |
293 | #else | 293 | #else | |
294 | # define lexi_end(tk) (tk) | 294 | # define lexi_end(tk) (tk) | |
295 | #endif | 295 | #endif | |
296 | 296 | |||
297 | token_type | 297 | token_type | |
298 | lexi(struct parser_state *state) | 298 | lexi(struct parser_state *state) | |
299 | { | 299 | { | |
300 | int unary_delim; /* this is set to 1 if the current token | 300 | int unary_delim; /* this is set to 1 if the current token | |
301 | * forces a following operator to be unary */ | 301 | * forces a following operator to be unary */ | |
302 | token_type code; /* internal code to be returned */ | 302 | token_type code; /* internal code to be returned */ | |
303 | char qchar; /* the delimiter character for a string */ | 303 | char qchar; /* the delimiter character for a string */ | |
304 | 304 | |||
305 | e_token = s_token; /* point to start of place to save token */ | 305 | e_token = s_token; /* point to start of place to save token */ | |
306 | unary_delim = false; | 306 | unary_delim = false; | |
307 | state->col_1 = state->last_nl; /* tell world that this token started | 307 | state->col_1 = state->last_nl; /* tell world that this token started | |
308 | * in column 1 iff the last thing | 308 | * in column 1 iff the last thing | |
309 | * scanned was a newline */ | 309 | * scanned was a newline */ | |
310 | state->last_nl = false; | 310 | state->last_nl = false; | |
311 | 311 | |||
312 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ | 312 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ | |
313 | state->col_1 = false; /* leading blanks imply token is not in column | 313 | state->col_1 = false; /* leading blanks imply token is not in column | |
314 | * 1 */ | 314 | * 1 */ | |
315 | inbuf_skip(); | 315 | inbuf_skip(); | |
316 | } | 316 | } | |
317 | 317 | |||
318 | /* Scan an alphanumeric token */ | 318 | /* Scan an alphanumeric token */ | |
319 | if (isalnum((unsigned char)*buf_ptr) || | 319 | if (isalnum((unsigned char)*buf_ptr) || | |
320 | *buf_ptr == '_' || *buf_ptr == '$' || | 320 | *buf_ptr == '_' || *buf_ptr == '$' || | |
321 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | 321 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | |
322 | /* | 322 | /* | |
323 | * we have a character or number | 323 | * we have a character or number | |
324 | */ | 324 | */ | |
325 | struct templ *p; | 325 | struct templ *p; | |
326 | 326 | |||
327 | if (isdigit((unsigned char)*buf_ptr) || | 327 | if (isdigit((unsigned char)*buf_ptr) || | |
328 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | 328 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | |
329 | char s; | 329 | char s; | |
330 | unsigned char i; | 330 | unsigned char i; | |
331 | 331 | |||
332 | for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) { | 332 | for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) { | |
333 | i = (unsigned char)*buf_ptr; | 333 | i = (unsigned char)*buf_ptr; | |
334 | if (i >= nitems(table) || table[i] == NULL || | 334 | if (i >= nitems(table) || table[i] == NULL || | |
335 | table[i][s - 'A'] == ' ') { | 335 | table[i][s - 'A'] == ' ') { | |
336 | s = table[0][s - 'A']; | 336 | s = table[0][s - 'A']; | |
337 | break; | 337 | break; | |
338 | } | 338 | } | |
339 | s = table[i][s - 'A']; | 339 | s = table[i][s - 'A']; | |
340 | check_size_token(1); | 340 | check_size_token(1); | |
341 | *e_token++ = inbuf_next(); | 341 | *e_token++ = inbuf_next(); | |
342 | } | 342 | } | |
343 | /* s now indicates the type: f(loating), i(integer), u(nknown) */ | 343 | /* s now indicates the type: f(loating), i(integer), u(nknown) */ | |
344 | } | 344 | } else { | |
345 | else | |||
346 | while (isalnum((unsigned char)*buf_ptr) || | 345 | while (isalnum((unsigned char)*buf_ptr) || | |
347 | *buf_ptr == '\\' || | 346 | *buf_ptr == '\\' || | |
348 | *buf_ptr == '_' || *buf_ptr == '$') { | 347 | *buf_ptr == '_' || *buf_ptr == '$') { | |
349 | /* fill_buffer() terminates buffer with newline */ | 348 | /* fill_buffer() terminates buffer with newline */ | |
350 | if (*buf_ptr == '\\') { | 349 | if (*buf_ptr == '\\') { | |
351 | if (buf_ptr[1] == '\n') { | 350 | if (buf_ptr[1] == '\n') { | |
352 | buf_ptr += 2; | 351 | buf_ptr += 2; | |
353 | if (buf_ptr >= buf_end) | 352 | if (buf_ptr >= buf_end) | |
354 | fill_buffer(); | 353 | fill_buffer(); | |
355 | } else | 354 | } else | |
356 | break; | 355 | break; | |
357 | } | 356 | } | |
358 | check_size_token(1); | 357 | check_size_token(1); | |
359 | *e_token++ = inbuf_next(); | 358 | *e_token++ = inbuf_next(); | |
360 | } | 359 | } | |
360 | } | |||
361 | *e_token = '\0'; | 361 | *e_token = '\0'; | |
362 | 362 | |||
363 | if (s_token[0] == 'L' && s_token[1] == '\0' && | 363 | if (s_token[0] == 'L' && s_token[1] == '\0' && | |
364 | (*buf_ptr == '"' || *buf_ptr == '\'')) | 364 | (*buf_ptr == '"' || *buf_ptr == '\'')) | |
365 | return lexi_end(string_prefix); | 365 | return lexi_end(string_prefix); | |
366 | 366 | |||
367 | while (*buf_ptr == ' ' || *buf_ptr == '\t') /* get rid of blanks */ | 367 | while (*buf_ptr == ' ' || *buf_ptr == '\t') /* get rid of blanks */ | |
368 | inbuf_next(); | 368 | inbuf_next(); | |
369 | state->keyword = rw_0; | 369 | state->keyword = rw_0; | |
370 | if (state->last_token == keyword_struct_union_enum && | 370 | if (state->last_token == keyword_struct_union_enum && | |
371 | !state->p_l_follow) { | 371 | !state->p_l_follow) { | |
372 | /* if last token was 'struct' and we're not in parentheses, then | 372 | /* if last token was 'struct' and we're not in parentheses, then | |
373 | * this token should be treated as a declaration */ | 373 | * this token should be treated as a declaration */ | |
374 | state->last_u_d = true; | 374 | state->last_u_d = true; | |
375 | return lexi_end(decl); | 375 | return lexi_end(decl); | |
376 | } | 376 | } | |
377 | /* | 377 | /* | |
378 | * Operator after identifier is binary unless last token was 'struct' | 378 | * Operator after identifier is binary unless last token was 'struct' | |
379 | */ | 379 | */ | |
380 | state->last_u_d = (state->last_token == keyword_struct_union_enum); | 380 | state->last_u_d = (state->last_token == keyword_struct_union_enum); | |
381 | 381 | |||
382 | p = bsearch(s_token, specials, sizeof specials / sizeof specials[0], | 382 | p = bsearch(s_token, specials, sizeof specials / sizeof specials[0], | |
383 | sizeof specials[0], compare_templ_array); | 383 | sizeof specials[0], compare_templ_array); | |
384 | if (p == NULL) { /* not a special keyword... */ | 384 | if (p == NULL) { /* not a special keyword... */ | |
385 | char *u; | 385 | char *u; | |
386 | 386 | |||
387 | /* ... so maybe a type_t or a typedef */ | 387 | /* ... so maybe a type_t or a typedef */ | |
388 | if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && | 388 | if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && | |
389 | strcmp(u, "_t") == 0) || (typename_top >= 0 && | 389 | strcmp(u, "_t") == 0) || (typename_top >= 0 && | |
390 | bsearch(s_token, typenames, typename_top + 1, | 390 | bsearch(s_token, typenames, typename_top + 1, | |
391 | sizeof typenames[0], compare_string_array))) { | 391 | sizeof typenames[0], compare_string_array))) { | |
392 | state->keyword = rw_type; | 392 | state->keyword = rw_type; | |
393 | state->last_u_d = true; | 393 | state->last_u_d = true; | |
394 | goto found_typename; | 394 | goto found_typename; | |
395 | } | 395 | } | |
396 | } else { /* we have a keyword */ | 396 | } else { /* we have a keyword */ | |
397 | state->keyword = p->rwcode; | 397 | state->keyword = p->rwcode; | |
398 | state->last_u_d = true; | 398 | state->last_u_d = true; | |
399 | switch (p->rwcode) { | 399 | switch (p->rwcode) { | |
400 | case rw_switch: | 400 | case rw_switch: | |
401 | return lexi_end(switch_expr); | 401 | return lexi_end(switch_expr); | |
402 | case rw_case_or_default: | 402 | case rw_case_or_default: | |
403 | return lexi_end(case_label); | 403 | return lexi_end(case_label); | |
404 | case rw_struct_or_union_or_enum: | 404 | case rw_struct_or_union_or_enum: | |
405 | case rw_type: | 405 | case rw_type: | |
406 | found_typename: | 406 | found_typename: | |
407 | if (state->p_l_follow) { | 407 | if (state->p_l_follow) { | |
408 | /* inside parens: cast, param list, offsetof or sizeof */ | 408 | /* inside parens: cast, param list, offsetof or sizeof */ | |
409 | state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; | 409 | state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; | |
410 | } | 410 | } | |
411 | if (state->last_token == period || state->last_token == unary_op) { | 411 | if (state->last_token == period || state->last_token == unary_op) { | |
412 | state->keyword = rw_0; | 412 | state->keyword = rw_0; | |
413 | break; | 413 | break; | |
414 | } | 414 | } | |
415 | if (p != NULL && p->rwcode == rw_struct_or_union_or_enum) | 415 | if (p != NULL && p->rwcode == rw_struct_or_union_or_enum) | |
416 | return lexi_end(keyword_struct_union_enum); | 416 | return lexi_end(keyword_struct_union_enum); | |
417 | if (state->p_l_follow) | 417 | if (state->p_l_follow) | |
418 | break; | 418 | break; | |
419 | return lexi_end(decl); | 419 | return lexi_end(decl); | |
420 | 420 | |||
421 | case rw_for_or_if_or_while: | 421 | case rw_for_or_if_or_while: | |
422 | return lexi_end(keyword_for_if_while); | 422 | return lexi_end(keyword_for_if_while); | |
423 | 423 | |||
424 | case rw_do_or_else: | 424 | case rw_do_or_else: | |
425 | return lexi_end(keyword_do_else); | 425 | return lexi_end(keyword_do_else); | |
426 | 426 | |||
427 | case rw_storage_class: | 427 | case rw_storage_class: | |
428 | return lexi_end(storage_class); | 428 | return lexi_end(storage_class); | |
429 | 429 | |||
430 | case rw_typedef: | 430 | case rw_typedef: | |
431 | return lexi_end(type_def); | 431 | return lexi_end(type_def); | |
432 | 432 | |||
433 | default: /* all others are treated like any other | 433 | default: /* all others are treated like any other | |
434 | * identifier */ | 434 | * identifier */ | |
435 | return lexi_end(ident); | 435 | return lexi_end(ident); | |
436 | } /* end of switch */ | 436 | } /* end of switch */ | |
437 | } /* end of if (found_it) */ | 437 | } /* end of if (found_it) */ | |
438 | if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && | 438 | if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && | |
439 | state->in_parameter_declaration == 0 && state->block_init == 0) { | 439 | state->in_parameter_declaration == 0 && state->block_init == 0) { | |
440 | char *tp = buf_ptr; | 440 | char *tp = buf_ptr; | |
441 | while (tp < buf_end) | 441 | while (tp < buf_end) | |
442 | if (*tp++ == ')' && (*tp == ';' || *tp == ',')) | 442 | if (*tp++ == ')' && (*tp == ';' || *tp == ',')) | |
443 | goto not_proc; | 443 | goto not_proc; | |
444 | strncpy(state->procname, token, sizeof state->procname - 1); | 444 | strncpy(state->procname, token, sizeof state->procname - 1); | |
445 | if (state->in_decl) | 445 | if (state->in_decl) | |
446 | state->in_parameter_declaration = 1; | 446 | state->in_parameter_declaration = 1; | |
447 | return lexi_end(funcname); | 447 | return lexi_end(funcname); | |
448 | not_proc:; | 448 | not_proc:; | |
449 | } | 449 | } | |
450 | /* | 450 | /* | |
451 | * The following hack attempts to guess whether or not the current | 451 | * The following hack attempts to guess whether or not the current | |
452 | * token is in fact a declaration keyword -- one that has been | 452 | * token is in fact a declaration keyword -- one that has been | |
453 | * typedefd | 453 | * typedefd | |
454 | */ | 454 | */ | |
455 | else if (!state->p_l_follow && !state->block_init && | 455 | else if (!state->p_l_follow && !state->block_init && | |
456 | !state->in_stmt && | 456 | !state->in_stmt && | |
457 | ((*buf_ptr == '*' && buf_ptr[1] != '=') || | 457 | ((*buf_ptr == '*' && buf_ptr[1] != '=') || | |
458 | isalpha((unsigned char)*buf_ptr)) && | 458 | isalpha((unsigned char)*buf_ptr)) && | |
459 | (state->last_token == semicolon || state->last_token == lbrace || | 459 | (state->last_token == semicolon || state->last_token == lbrace || | |
460 | state->last_token == rbrace)) { | 460 | state->last_token == rbrace)) { | |
461 | state->keyword = rw_type; | 461 | state->keyword = rw_type; | |
462 | state->last_u_d = true; | 462 | state->last_u_d = true; | |
463 | return lexi_end(decl); | 463 | return lexi_end(decl); | |
464 | } | 464 | } | |
465 | if (state->last_token == decl) /* if this is a declared variable, | 465 | if (state->last_token == decl) /* if this is a declared variable, | |
466 | * then following sign is unary */ | 466 | * then following sign is unary */ | |
467 | state->last_u_d = true; /* will make "int a -1" work */ | 467 | state->last_u_d = true; /* will make "int a -1" work */ | |
468 | return lexi_end(ident); /* the ident is not in the list */ | 468 | return lexi_end(ident); /* the ident is not in the list */ | |
469 | } /* end of procesing for alpanum character */ | 469 | } /* end of procesing for alpanum character */ | |
470 | 470 | |||
471 | /* Scan a non-alphanumeric token */ | 471 | /* Scan a non-alphanumeric token */ | |
472 | 472 | |||
473 | check_size_token(3); /* things like "<<=" */ | 473 | check_size_token(3); /* things like "<<=" */ | |
474 | *e_token++ = inbuf_next(); /* if it is only a one-character token, it is | 474 | *e_token++ = inbuf_next(); /* if it is only a one-character token, it is | |
475 | * moved here */ | 475 | * moved here */ | |
476 | *e_token = '\0'; | 476 | *e_token = '\0'; | |
477 | 477 | |||
478 | switch (*token) { | 478 | switch (*token) { | |
479 | case '\n': | 479 | case '\n': | |
480 | unary_delim = state->last_u_d; | 480 | unary_delim = state->last_u_d; | |
481 | state->last_nl = true; /* remember that we just had a newline */ | 481 | state->last_nl = true; /* remember that we just had a newline */ | |
482 | code = (had_eof ? end_of_file : newline); | 482 | code = (had_eof ? end_of_file : newline); | |
483 | 483 | |||
484 | /* | 484 | /* | |
485 | * if data has been exhausted, the newline is a dummy, and we should | 485 | * if data has been exhausted, the newline is a dummy, and we should | |
486 | * return code to stop | 486 | * return code to stop | |
487 | */ | 487 | */ | |
488 | break; | 488 | break; | |
489 | 489 | |||
490 | case '\'': /* start of quoted character */ | 490 | case '\'': /* start of quoted character */ | |
491 | case '"': /* start of string */ | 491 | case '"': /* start of string */ | |
492 | qchar = *token; | 492 | qchar = *token; | |
493 | do { /* copy the string */ | 493 | do { /* copy the string */ | |
494 | while (1) { /* move one character or [/<char>]<char> */ | 494 | while (1) { /* move one character or [/<char>]<char> */ | |
495 | if (*buf_ptr == '\n') { | 495 | if (*buf_ptr == '\n') { | |
496 | diag(1, "Unterminated literal"); | 496 | diag(1, "Unterminated literal"); | |
497 | goto stop_lit; | 497 | goto stop_lit; | |
498 | } | 498 | } | |
499 | check_size_token(2); | 499 | check_size_token(2); | |
500 | *e_token = inbuf_next(); | 500 | *e_token = inbuf_next(); | |
501 | if (*e_token == '\\') { /* if escape, copy extra char */ | 501 | if (*e_token == '\\') { /* if escape, copy extra char */ | |
502 | if (*buf_ptr == '\n') /* check for escaped newline */ | 502 | if (*buf_ptr == '\n') /* check for escaped newline */ | |
503 | ++line_no; | 503 | ++line_no; | |
504 | *++e_token = inbuf_next(); | 504 | *++e_token = inbuf_next(); | |
505 | ++e_token; /* we must increment this again because we | 505 | ++e_token; /* we must increment this again because we | |
506 | * copied two chars */ | 506 | * copied two chars */ | |
507 | } | 507 | } else | |
508 | else | |||
509 | break; /* we copied one character */ | 508 | break; /* we copied one character */ | |
510 | } /* end of while (1) */ | 509 | } /* end of while (1) */ | |
511 | } while (*e_token++ != qchar); | 510 | } while (*e_token++ != qchar); | |
512 | stop_lit: | 511 | stop_lit: | |
513 | code = ident; | 512 | code = ident; | |
514 | break; | 513 | break; | |
515 | 514 | |||
516 | case ('('): | 515 | case ('('): | |
517 | case ('['): | 516 | case ('['): | |
518 | unary_delim = true; | 517 | unary_delim = true; | |
519 | code = lparen; | 518 | code = lparen; | |
520 | break; | 519 | break; | |
521 | 520 | |||
522 | case (')'): | 521 | case (')'): | |
523 | case (']'): | 522 | case (']'): | |
524 | code = rparen; | 523 | code = rparen; | |
525 | break; | 524 | break; | |
526 | 525 | |||
527 | case '#': | 526 | case '#': | |
528 | unary_delim = state->last_u_d; | 527 | unary_delim = state->last_u_d; | |
529 | code = preprocessing; | 528 | code = preprocessing; | |
530 | break; | 529 | break; | |
531 | 530 | |||
532 | case '?': | 531 | case '?': | |
533 | unary_delim = true; | 532 | unary_delim = true; | |
534 | code = question; | 533 | code = question; | |
535 | break; | 534 | break; | |
536 | 535 | |||
537 | case (':'): | 536 | case (':'): | |
538 | code = colon; | 537 | code = colon; | |
539 | unary_delim = true; | 538 | unary_delim = true; | |
540 | break; | 539 | break; | |
541 | 540 | |||
542 | case (';'): | 541 | case (';'): | |
543 | unary_delim = true; | 542 | unary_delim = true; | |
544 | code = semicolon; | 543 | code = semicolon; | |
545 | break; | 544 | break; | |
546 | 545 | |||
547 | case ('{'): | 546 | case ('{'): | |
548 | unary_delim = true; | 547 | unary_delim = true; | |
549 | 548 | |||
550 | /* | 549 | /* | |
551 | * if (state->in_or_st) state->block_init = 1; | 550 | * if (state->in_or_st) state->block_init = 1; | |
552 | */ | 551 | */ | |
553 | /* ? code = state->block_init ? lparen : lbrace; */ | 552 | /* ? code = state->block_init ? lparen : lbrace; */ | |
554 | code = lbrace; | 553 | code = lbrace; | |
555 | break; | 554 | break; | |
556 | 555 | |||
557 | case ('}'): | 556 | case ('}'): | |
558 | unary_delim = true; | 557 | unary_delim = true; | |
559 | /* ? code = state->block_init ? rparen : rbrace; */ | 558 | /* ? code = state->block_init ? rparen : rbrace; */ | |
560 | code = rbrace; | 559 | code = rbrace; | |
561 | break; | 560 | break; | |
562 | 561 | |||
563 | case 014: /* a form feed */ | 562 | case 014: /* a form feed */ | |
564 | unary_delim = state->last_u_d; | 563 | unary_delim = state->last_u_d; | |
565 | state->last_nl = true; /* remember this so we can set 'state->col_1' | 564 | state->last_nl = true; /* remember this so we can set 'state->col_1' | |
566 | * right */ | 565 | * right */ | |
567 | code = form_feed; | 566 | code = form_feed; | |
568 | break; | 567 | break; | |
569 | 568 | |||
570 | case (','): | 569 | case (','): | |
571 | unary_delim = true; | 570 | unary_delim = true; | |
572 | code = comma; | 571 | code = comma; | |
573 | break; | 572 | break; | |
574 | 573 | |||
575 | case '.': | 574 | case '.': | |
576 | unary_delim = false; | 575 | unary_delim = false; | |
577 | code = period; | 576 | code = period; | |
578 | break; | 577 | break; | |
579 | 578 | |||
580 | case '-': | 579 | case '-': | |
581 | case '+': /* check for -, +, --, ++ */ | 580 | case '+': /* check for -, +, --, ++ */ | |
582 | code = (state->last_u_d ? unary_op : binary_op); | 581 | code = (state->last_u_d ? unary_op : binary_op); | |
583 | unary_delim = true; | 582 | unary_delim = true; | |
584 | 583 | |||
585 | if (*buf_ptr == token[0]) { | 584 | if (*buf_ptr == token[0]) { | |
586 | /* check for doubled character */ | 585 | /* check for doubled character */ | |
587 | *e_token++ = *buf_ptr++; | 586 | *e_token++ = *buf_ptr++; | |
588 | /* buffer overflow will be checked at end of loop */ | 587 | /* buffer overflow will be checked at end of loop */ | |
589 | if (state->last_token == ident || state->last_token == rparen) { | 588 | if (state->last_token == ident || state->last_token == rparen) { | |
590 | code = (state->last_u_d ? unary_op : postfix_op); | 589 | code = (state->last_u_d ? unary_op : postfix_op); | |
591 | /* check for following ++ or -- */ | 590 | /* check for following ++ or -- */ | |
592 | unary_delim = false; | 591 | unary_delim = false; | |
593 | } | 592 | } | |
594 | } | 593 | } else if (*buf_ptr == '=') | |
595 | else if (*buf_ptr == '=') | |||
596 | /* check for operator += */ | 594 | /* check for operator += */ | |
597 | *e_token++ = *buf_ptr++; | 595 | *e_token++ = *buf_ptr++; | |
598 | else if (*buf_ptr == '>') { | 596 | else if (*buf_ptr == '>') { | |
599 | /* check for operator -> */ | 597 | /* check for operator -> */ | |
600 | *e_token++ = *buf_ptr++; | 598 | *e_token++ = *buf_ptr++; | |
601 | unary_delim = false; | 599 | unary_delim = false; | |
602 | code = unary_op; | 600 | code = unary_op; | |
603 | state->want_blank = false; | 601 | state->want_blank = false; | |
604 | } | 602 | } | |
605 | break; /* buffer overflow will be checked at end of | 603 | break; /* buffer overflow will be checked at end of | |
606 | * switch */ | 604 | * switch */ | |
607 | 605 | |||
608 | case '=': | 606 | case '=': | |
609 | if (state->in_or_st) | 607 | if (state->in_or_st) | |
610 | state->block_init = 1; | 608 | state->block_init = 1; | |
611 | if (*buf_ptr == '=') { /* == */ | 609 | if (*buf_ptr == '=') { /* == */ | |
612 | *e_token++ = '='; /* Flip =+ to += */ | 610 | *e_token++ = '='; /* Flip =+ to += */ | |
613 | buf_ptr++; | 611 | buf_ptr++; | |
614 | *e_token = 0; | 612 | *e_token = 0; | |
615 | } | 613 | } | |
616 | code = binary_op; | 614 | code = binary_op; | |
617 | unary_delim = true; | 615 | unary_delim = true; | |
618 | break; | 616 | break; | |
619 | /* can drop thru!!! */ | 617 | /* can drop thru!!! */ | |
620 | 618 | |||
621 | case '>': | 619 | case '>': | |
622 | case '<': | 620 | case '<': | |
623 | case '!': /* ops like <, <<, <=, !=, etc */ | 621 | case '!': /* ops like <, <<, <=, !=, etc */ | |
624 | if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') | 622 | if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') | |
625 | *e_token++ = inbuf_next(); | 623 | *e_token++ = inbuf_next(); | |
626 | if (*buf_ptr == '=') | 624 | if (*buf_ptr == '=') | |
627 | *e_token++ = *buf_ptr++; | 625 | *e_token++ = *buf_ptr++; | |
628 | code = (state->last_u_d ? unary_op : binary_op); | 626 | code = (state->last_u_d ? unary_op : binary_op); | |
629 | unary_delim = true; | 627 | unary_delim = true; | |
630 | break; | 628 | break; | |
631 | 629 | |||
632 | case '*': | 630 | case '*': | |
633 | unary_delim = true; | 631 | unary_delim = true; | |
634 | if (!state->last_u_d) { | 632 | if (!state->last_u_d) { | |
635 | if (*buf_ptr == '=') | 633 | if (*buf_ptr == '=') | |
636 | *e_token++ = *buf_ptr++; | 634 | *e_token++ = *buf_ptr++; | |
637 | code = binary_op; | 635 | code = binary_op; | |
638 | break; | 636 | break; | |
639 | } | 637 | } | |
640 | while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { | 638 | while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { | |
641 | if (*buf_ptr == '*') { | 639 | if (*buf_ptr == '*') { | |
642 | check_size_token(1); | 640 | check_size_token(1); | |
643 | *e_token++ = *buf_ptr; | 641 | *e_token++ = *buf_ptr; | |
644 | } | 642 | } | |
645 | inbuf_skip(); | 643 | inbuf_skip(); | |
646 | } | 644 | } | |
647 | if (ps.in_decl) { | 645 | if (ps.in_decl) { | |
648 | char *tp = buf_ptr; | 646 | char *tp = buf_ptr; | |
649 | 647 | |||
650 | while (isalpha((unsigned char)*tp) || | 648 | while (isalpha((unsigned char)*tp) || | |
651 | isspace((unsigned char)*tp)) { | 649 | isspace((unsigned char)*tp)) { | |
652 | if (++tp >= buf_end) | 650 | if (++tp >= buf_end) | |
653 | fill_buffer(); | 651 | fill_buffer(); | |
654 | } | 652 | } | |
655 | if (*tp == '(') | 653 | if (*tp == '(') | |
656 | ps.procname[0] = ' '; | 654 | ps.procname[0] = ' '; | |
657 | } | 655 | } | |
658 | code = unary_op; | 656 | code = unary_op; | |
659 | break; | 657 | break; | |
660 | 658 | |||
661 | default: | 659 | default: | |
662 | if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { | 660 | if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { | |
663 | /* it is start of comment */ | 661 | /* it is start of comment */ | |
664 | *e_token++ = inbuf_next(); | 662 | *e_token++ = inbuf_next(); | |
665 | 663 | |||
666 | code = comment; | 664 | code = comment; | |
667 | unary_delim = state->last_u_d; | 665 | unary_delim = state->last_u_d; | |
668 | break; | 666 | break; | |
669 | } | 667 | } | |
670 | while (e_token[-1] == *buf_ptr || *buf_ptr == '=') { | 668 | while (e_token[-1] == *buf_ptr || *buf_ptr == '=') { | |
671 | /* | 669 | /* | |
672 | * handle ||, &&, etc, and also things as in int *****i | 670 | * handle ||, &&, etc, and also things as in int *****i | |
673 | */ | 671 | */ | |
674 | check_size_token(1); | 672 | check_size_token(1); | |
675 | *e_token++ = inbuf_next(); | 673 | *e_token++ = inbuf_next(); | |
676 | } | 674 | } | |
677 | code = (state->last_u_d ? unary_op : binary_op); | 675 | code = (state->last_u_d ? unary_op : binary_op); | |
678 | unary_delim = true; | 676 | unary_delim = true; | |
679 | 677 | |||
680 | 678 | |||
681 | } /* end of switch */ | 679 | } /* end of switch */ | |
682 | if (buf_ptr >= buf_end) /* check for input buffer empty */ | 680 | if (buf_ptr >= buf_end) /* check for input buffer empty */ | |
683 | fill_buffer(); | 681 | fill_buffer(); | |
684 | state->last_u_d = unary_delim; | 682 | state->last_u_d = unary_delim; | |
685 | check_size_token(1); | 683 | check_size_token(1); | |
686 | *e_token = '\0'; /* null terminate the token */ | 684 | *e_token = '\0'; /* null terminate the token */ | |
687 | return lexi_end(code); | 685 | return lexi_end(code); | |
688 | } | 686 | } | |
689 | 687 | |||
690 | void | 688 | void | |
691 | alloc_typenames(void) | 689 | alloc_typenames(void) | |
692 | { | 690 | { | |
693 | 691 | |||
694 | typenames = malloc(sizeof(typenames[0]) * (typename_count = 16)); | 692 | typenames = malloc(sizeof(typenames[0]) * (typename_count = 16)); | |
695 | if (typenames == NULL) | 693 | if (typenames == NULL) | |
696 | err(1, NULL); | 694 | err(1, NULL); | |
697 | } | 695 | } | |
698 | 696 | |||
699 | void | 697 | void | |
700 | add_typename(const char *key) | 698 | add_typename(const char *key) | |
701 | { | 699 | { | |
702 | int comparison; | 700 | int comparison; | |
703 | const char *copy; | 701 | const char *copy; | |
704 | 702 | |||
705 | if (typename_top + 1 >= typename_count) { | 703 | if (typename_top + 1 >= typename_count) { | |
706 | typenames = realloc((void *)typenames, | 704 | typenames = realloc((void *)typenames, | |
707 | sizeof(typenames[0]) * (typename_count *= 2)); | 705 | sizeof(typenames[0]) * (typename_count *= 2)); | |
708 | if (typenames == NULL) | 706 | if (typenames == NULL) | |
709 | err(1, NULL); | 707 | err(1, NULL); | |
710 | } | 708 | } | |
711 | if (typename_top == -1) | 709 | if (typename_top == -1) | |
712 | typenames[++typename_top] = copy = strdup(key); | 710 | typenames[++typename_top] = copy = strdup(key); | |
713 | else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { | 711 | else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { | |
714 | /* take advantage of sorted input */ | 712 | /* take advantage of sorted input */ | |
715 | if (comparison == 0) /* remove duplicates */ | 713 | if (comparison == 0) /* remove duplicates */ | |
716 | return; | 714 | return; | |
717 | typenames[++typename_top] = copy = strdup(key); | 715 | typenames[++typename_top] = copy = strdup(key); | |
718 | } | 716 | } else { | |
719 | else { | |||
720 | int p; | 717 | int p; | |
721 | 718 | |||
722 | for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) | 719 | for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) | |
723 | /* find place for the new key */; | 720 | /* find place for the new key */; | |
724 | if (comparison == 0) /* remove duplicates */ | 721 | if (comparison == 0) /* remove duplicates */ | |
725 | return; | 722 | return; | |
726 | memmove(&typenames[p + 1], &typenames[p], | 723 | memmove(&typenames[p + 1], &typenames[p], | |
727 | sizeof(typenames[0]) * (++typename_top - p)); | 724 | sizeof(typenames[0]) * (++typename_top - p)); | |
728 | typenames[p] = copy = strdup(key); | 725 | typenames[p] = copy = strdup(key); | |
729 | } | 726 | } | |
730 | 727 | |||
731 | if (copy == NULL) | 728 | if (copy == NULL) | |
732 | err(1, NULL); | 729 | err(1, NULL); | |
733 | } | 730 | } |
--- src/usr.bin/indent/parse.c 2021/03/09 19:14:39 1.17
+++ src/usr.bin/indent/parse.c 2021/03/12 23:10:18 1.18
@@ -1,309 +1,307 @@ | @@ -1,309 +1,307 @@ | |||
1 | /* $NetBSD: parse.c,v 1.17 2021/03/09 19:14:39 rillig Exp $ */ | 1 | /* $NetBSD: parse.c,v 1.18 2021/03/12 23:10:18 rillig Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * SPDX-License-Identifier: BSD-4-Clause | 4 | * SPDX-License-Identifier: BSD-4-Clause | |
5 | * | 5 | * | |
6 | * Copyright (c) 1985 Sun Microsystems, Inc. | 6 | * Copyright (c) 1985 Sun Microsystems, Inc. | |
7 | * Copyright (c) 1980, 1993 | 7 | * Copyright (c) 1980, 1993 | |
8 | * The Regents of the University of California. All rights reserved. | 8 | * The Regents of the University of California. All rights reserved. | |
9 | * All rights reserved. | 9 | * All rights reserved. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
15 | * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. | |
16 | * 2. Redistributions in binary form must reproduce the above copyright | 16 | * 2. Redistributions in binary form must reproduce the above copyright | |
17 | * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the | |
18 | * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. | |
19 | * 3. All advertising materials mentioning features or use of this software | 19 | * 3. All advertising materials mentioning features or use of this software | |
20 | * must display the following acknowledgement: | 20 | * must display the following acknowledgement: | |
21 | * This product includes software developed by the University of | 21 | * This product includes software developed by the University of | |
22 | * California, Berkeley and its contributors. | 22 | * California, Berkeley and its contributors. | |
23 | * 4. Neither the name of the University nor the names of its contributors | 23 | * 4. Neither the name of the University nor the names of its contributors | |
24 | * may be used to endorse or promote products derived from this software | 24 | * may be used to endorse or promote products derived from this software | |
25 | * without specific prior written permission. | 25 | * without specific prior written permission. | |
26 | * | 26 | * | |
27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 27 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 28 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 29 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 30 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 35 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 36 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
37 | * SUCH DAMAGE. | 37 | * SUCH DAMAGE. | |
38 | */ | 38 | */ | |
39 | 39 | |||
40 | #if 0 | 40 | #if 0 | |
41 | #ifndef lint | 41 | #ifndef lint | |
42 | static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93"; | 42 | static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93"; | |
43 | #endif /* not lint */ | 43 | #endif /* not lint */ | |
44 | #endif | 44 | #endif | |
45 | 45 | |||
46 | #include <sys/cdefs.h> | 46 | #include <sys/cdefs.h> | |
47 | #ifndef lint | 47 | #ifndef lint | |
48 | #if defined(__NetBSD__) | 48 | #if defined(__NetBSD__) | |
49 | __RCSID("$FreeBSD$"); | 49 | __RCSID("$FreeBSD$"); | |
50 | #else | 50 | #else | |
51 | __FBSDID("$FreeBSD: head/usr.bin/indent/parse.c 337651 2018-08-11 19:20:06Z pstef $"); | 51 | __FBSDID("$FreeBSD: head/usr.bin/indent/parse.c 337651 2018-08-11 19:20:06Z pstef $"); | |
52 | #endif | 52 | #endif | |
53 | #endif | 53 | #endif | |
54 | 54 | |||
55 | #include <err.h> | 55 | #include <err.h> | |
56 | #include <stdio.h> | 56 | #include <stdio.h> | |
57 | 57 | |||
58 | #include "indent.h" | 58 | #include "indent.h" | |
59 | 59 | |||
60 | static void reduce(void); | 60 | static void reduce(void); | |
61 | 61 | |||
62 | void | 62 | void | |
63 | parse(token_type tk) /* tk: the code for the construct scanned */ | 63 | parse(token_type tk) /* tk: the code for the construct scanned */ | |
64 | { | 64 | { | |
65 | int i; | 65 | int i; | |
66 | 66 | |||
67 | #ifdef debug | 67 | #ifdef debug | |
68 | printf("parse token: '%s' \"%s\"\n", token_type_name(tk), token); | 68 | printf("parse token: '%s' \"%s\"\n", token_type_name(tk), token); | |
69 | #endif | 69 | #endif | |
70 | 70 | |||
71 | while (ps.p_stack[ps.tos] == if_expr_stmt && tk != keyword_else) { | 71 | while (ps.p_stack[ps.tos] == if_expr_stmt && tk != keyword_else) { | |
72 | /* true if we have an if without an else */ | 72 | /* true if we have an if without an else */ | |
73 | ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt | 73 | ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt | |
74 | * reduction */ | 74 | * reduction */ | |
75 | reduce(); /* see if this allows any reduction */ | 75 | reduce(); /* see if this allows any reduction */ | |
76 | } | 76 | } | |
77 | 77 | |||
78 | 78 | |||
79 | switch (tk) { /* go on and figure out what to do with the | 79 | switch (tk) { /* go on and figure out what to do with the | |
80 | * input */ | 80 | * input */ | |
81 | 81 | |||
82 | case decl: /* scanned a declaration word */ | 82 | case decl: /* scanned a declaration word */ | |
83 | ps.search_brace = opt.btype_2; | 83 | ps.search_brace = opt.btype_2; | |
84 | /* indicate that following brace should be on same line */ | 84 | /* indicate that following brace should be on same line */ | |
85 | if (ps.p_stack[ps.tos] != decl) { /* only put one declaration | 85 | if (ps.p_stack[ps.tos] != decl) { /* only put one declaration | |
86 | * onto stack */ | 86 | * onto stack */ | |
87 | break_comma = true; /* while in declaration, newline should be | 87 | break_comma = true; /* while in declaration, newline should be | |
88 | * forced after comma */ | 88 | * forced after comma */ | |
89 | ps.p_stack[++ps.tos] = decl; | 89 | ps.p_stack[++ps.tos] = decl; | |
90 | ps.il[ps.tos] = ps.i_l_follow; | 90 | ps.il[ps.tos] = ps.i_l_follow; | |
91 | 91 | |||
92 | if (opt.ljust_decl) {/* only do if we want left justified | 92 | if (opt.ljust_decl) {/* only do if we want left justified | |
93 | * declarations */ | 93 | * declarations */ | |
94 | ps.ind_level = 0; | 94 | ps.ind_level = 0; | |
95 | for (i = ps.tos - 1; i > 0; --i) | 95 | for (i = ps.tos - 1; i > 0; --i) | |
96 | if (ps.p_stack[i] == decl) | 96 | if (ps.p_stack[i] == decl) | |
97 | ++ps.ind_level; /* indentation is number of | 97 | ++ps.ind_level; /* indentation is number of | |
98 | * declaration levels deep we are */ | 98 | * declaration levels deep we are */ | |
99 | ps.i_l_follow = ps.ind_level; | 99 | ps.i_l_follow = ps.ind_level; | |
100 | } | 100 | } | |
101 | } | 101 | } | |
102 | break; | 102 | break; | |
103 | 103 | |||
104 | case if_expr: /* 'if' '(' <expr> ')' */ | 104 | case if_expr: /* 'if' '(' <expr> ')' */ | |
105 | if (ps.p_stack[ps.tos] == if_expr_stmt_else && opt.else_if) { | 105 | if (ps.p_stack[ps.tos] == if_expr_stmt_else && opt.else_if) { | |
106 | /* | 106 | /* | |
107 | * Note that the stack pointer here is decremented, effectively | 107 | * Note that the stack pointer here is decremented, effectively | |
108 | * reducing "else if" to "if". This saves a lot of stack space | 108 | * reducing "else if" to "if". This saves a lot of stack space | |
109 | * in case of a long "if-else-if ... else-if" sequence. | 109 | * in case of a long "if-else-if ... else-if" sequence. | |
110 | */ | 110 | */ | |
111 | ps.i_l_follow = ps.il[ps.tos--]; | 111 | ps.i_l_follow = ps.il[ps.tos--]; | |
112 | } | 112 | } | |
113 | /* the rest is the same as for keyword_do and for_exprs */ | 113 | /* the rest is the same as for keyword_do and for_exprs */ | |
114 | /* FALLTHROUGH */ | 114 | /* FALLTHROUGH */ | |
115 | case keyword_do: /* 'do' */ | 115 | case keyword_do: /* 'do' */ | |
116 | case for_exprs: /* 'for' (...) */ | 116 | case for_exprs: /* 'for' (...) */ | |
117 | ps.p_stack[++ps.tos] = tk; | 117 | ps.p_stack[++ps.tos] = tk; | |
118 | ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; | 118 | ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; | |
119 | ++ps.i_l_follow; /* subsequent statements should be indented 1 */ | 119 | ++ps.i_l_follow; /* subsequent statements should be indented 1 */ | |
120 | ps.search_brace = opt.btype_2; | 120 | ps.search_brace = opt.btype_2; | |
121 | break; | 121 | break; | |
122 | 122 | |||
123 | case lbrace: /* scanned { */ | 123 | case lbrace: /* scanned { */ | |
124 | break_comma = false; /* don't break comma in an initial list */ | 124 | break_comma = false; /* don't break comma in an initial list */ | |
125 | if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl | 125 | if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl | |
126 | || ps.p_stack[ps.tos] == stmt_list) | 126 | || ps.p_stack[ps.tos] == stmt_list) | |
127 | ++ps.i_l_follow; /* it is a random, isolated stmt group or a | 127 | ++ps.i_l_follow; /* it is a random, isolated stmt group or a | |
128 | * declaration */ | 128 | * declaration */ | |
129 | else { | 129 | else { | |
130 | if (s_code == e_code) { | 130 | if (s_code == e_code) { | |
131 | /* | 131 | /* | |
132 | * only do this if there is nothing on the line | 132 | * only do this if there is nothing on the line | |
133 | */ | 133 | */ | |
134 | --ps.ind_level; | 134 | --ps.ind_level; | |
135 | /* | 135 | /* | |
136 | * it is a group as part of a while, for, etc. | 136 | * it is a group as part of a while, for, etc. | |
137 | */ | 137 | */ | |
138 | if (ps.p_stack[ps.tos] == switch_expr && opt.case_indent >= 1) | 138 | if (ps.p_stack[ps.tos] == switch_expr && opt.case_indent >= 1) | |
139 | --ps.ind_level; | 139 | --ps.ind_level; | |
140 | /* | 140 | /* | |
141 | * for a switch, brace should be two levels out from the code | 141 | * for a switch, brace should be two levels out from the code | |
142 | */ | 142 | */ | |
143 | } | 143 | } | |
144 | } | 144 | } | |
145 | 145 | |||
146 | ps.p_stack[++ps.tos] = lbrace; | 146 | ps.p_stack[++ps.tos] = lbrace; | |
147 | ps.il[ps.tos] = ps.ind_level; | 147 | ps.il[ps.tos] = ps.ind_level; | |
148 | ps.p_stack[++ps.tos] = stmt; | 148 | ps.p_stack[++ps.tos] = stmt; | |
149 | /* allow null stmt between braces */ | 149 | /* allow null stmt between braces */ | |
150 | ps.il[ps.tos] = ps.i_l_follow; | 150 | ps.il[ps.tos] = ps.i_l_follow; | |
151 | break; | 151 | break; | |
152 | 152 | |||
153 | case while_expr: /* 'while' '(' <expr> ')' */ | 153 | case while_expr: /* 'while' '(' <expr> ')' */ | |
154 | if (ps.p_stack[ps.tos] == do_stmt) { | 154 | if (ps.p_stack[ps.tos] == do_stmt) { | |
155 | /* it is matched with do stmt */ | 155 | /* it is matched with do stmt */ | |
156 | ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; | 156 | ps.ind_level = ps.i_l_follow = ps.il[ps.tos]; | |
157 | ps.p_stack[++ps.tos] = while_expr; | 157 | ps.p_stack[++ps.tos] = while_expr; | |
158 | ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; | 158 | ps.il[ps.tos] = ps.ind_level = ps.i_l_follow; | |
159 | } | 159 | } else { /* it is a while loop */ | |
160 | else { /* it is a while loop */ | |||
161 | ps.p_stack[++ps.tos] = while_expr; | 160 | ps.p_stack[++ps.tos] = while_expr; | |
162 | ps.il[ps.tos] = ps.i_l_follow; | 161 | ps.il[ps.tos] = ps.i_l_follow; | |
163 | ++ps.i_l_follow; | 162 | ++ps.i_l_follow; | |
164 | ps.search_brace = opt.btype_2; | 163 | ps.search_brace = opt.btype_2; | |
165 | } | 164 | } | |
166 | 165 | |||
167 | break; | 166 | break; | |
168 | 167 | |||
169 | case keyword_else: | 168 | case keyword_else: | |
170 | if (ps.p_stack[ps.tos] != if_expr_stmt) | 169 | if (ps.p_stack[ps.tos] != if_expr_stmt) | |
171 | diag(1, "Unmatched 'else'"); | 170 | diag(1, "Unmatched 'else'"); | |
172 | else { | 171 | else { | |
173 | ps.ind_level = ps.il[ps.tos]; /* indentation for else should | 172 | ps.ind_level = ps.il[ps.tos]; /* indentation for else should | |
174 | * be same as for if */ | 173 | * be same as for if */ | |
175 | ps.i_l_follow = ps.ind_level + 1; /* everything following should | 174 | ps.i_l_follow = ps.ind_level + 1; /* everything following should | |
176 | * be in 1 level */ | 175 | * be in 1 level */ | |
177 | ps.p_stack[ps.tos] = if_expr_stmt_else; | 176 | ps.p_stack[ps.tos] = if_expr_stmt_else; | |
178 | /* remember if with else */ | 177 | /* remember if with else */ | |
179 | ps.search_brace = opt.btype_2 | opt.else_if; | 178 | ps.search_brace = opt.btype_2 | opt.else_if; | |
180 | } | 179 | } | |
181 | break; | 180 | break; | |
182 | 181 | |||
183 | case rbrace: /* scanned a } */ | 182 | case rbrace: /* scanned a } */ | |
184 | /* stack should have <lbrace> <stmt> or <lbrace> <stmt_list> */ | 183 | /* stack should have <lbrace> <stmt> or <lbrace> <stmt_list> */ | |
185 | if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) { | 184 | if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) { | |
186 | ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; | 185 | ps.ind_level = ps.i_l_follow = ps.il[--ps.tos]; | |
187 | ps.p_stack[ps.tos] = stmt; | 186 | ps.p_stack[ps.tos] = stmt; | |
188 | } | 187 | } else | |
189 | else | |||
190 | diag(1, "Statement nesting error"); | 188 | diag(1, "Statement nesting error"); | |
191 | break; | 189 | break; | |
192 | 190 | |||
193 | case switch_expr: /* had switch (...) */ | 191 | case switch_expr: /* had switch (...) */ | |
194 | ps.p_stack[++ps.tos] = switch_expr; | 192 | ps.p_stack[++ps.tos] = switch_expr; | |
195 | ps.cstk[ps.tos] = case_ind; | 193 | ps.cstk[ps.tos] = case_ind; | |
196 | /* save current case indent level */ | 194 | /* save current case indent level */ | |
197 | ps.il[ps.tos] = ps.i_l_follow; | 195 | ps.il[ps.tos] = ps.i_l_follow; | |
198 | case_ind = ps.i_l_follow + opt.case_indent; /* cases should be one | 196 | case_ind = ps.i_l_follow + opt.case_indent; /* cases should be one | |
199 | * level down from | 197 | * level down from | |
200 | * switch */ | 198 | * switch */ | |
201 | ps.i_l_follow += opt.case_indent + 1; /* statements should be two | 199 | ps.i_l_follow += opt.case_indent + 1; /* statements should be two | |
202 | * levels in */ | 200 | * levels in */ | |
203 | ps.search_brace = opt.btype_2; | 201 | ps.search_brace = opt.btype_2; | |
204 | break; | 202 | break; | |
205 | 203 | |||
206 | case semicolon: /* this indicates a simple stmt */ | 204 | case semicolon: /* this indicates a simple stmt */ | |
207 | break_comma = false; /* turn off flag to break after commas in a | 205 | break_comma = false; /* turn off flag to break after commas in a | |
208 | * declaration */ | 206 | * declaration */ | |
209 | ps.p_stack[++ps.tos] = stmt; | 207 | ps.p_stack[++ps.tos] = stmt; | |
210 | ps.il[ps.tos] = ps.ind_level; | 208 | ps.il[ps.tos] = ps.ind_level; | |
211 | break; | 209 | break; | |
212 | 210 | |||
213 | default: /* this is an error */ | 211 | default: /* this is an error */ | |
214 | diag(1, "Unknown code to parser"); | 212 | diag(1, "Unknown code to parser"); | |
215 | return; | 213 | return; | |
216 | 214 | |||
217 | 215 | |||
218 | } /* end of switch */ | 216 | } /* end of switch */ | |
219 | 217 | |||
220 | if (ps.tos >= STACKSIZE - 1) | 218 | if (ps.tos >= STACKSIZE - 1) | |
221 | errx(1, "Parser stack overflow"); | 219 | errx(1, "Parser stack overflow"); | |
222 | 220 | |||
223 | reduce(); /* see if any reduction can be done */ | 221 | reduce(); /* see if any reduction can be done */ | |
224 | 222 | |||
225 | #ifdef debug | 223 | #ifdef debug | |
226 | printf("parse stack:"); | 224 | printf("parse stack:"); | |
227 | for (i = 1; i <= ps.tos; ++i) | 225 | for (i = 1; i <= ps.tos; ++i) | |
228 | printf(" ('%s' at %d)", token_type_name(ps.p_stack[i]), ps.il[i]); | 226 | printf(" ('%s' at %d)", token_type_name(ps.p_stack[i]), ps.il[i]); | |
229 | if (ps.tos == 0) | 227 | if (ps.tos == 0) | |
230 | printf(" empty"); | 228 | printf(" empty"); | |
231 | printf("\n"); | 229 | printf("\n"); | |
232 | #endif | 230 | #endif | |
233 | } | 231 | } | |
234 | 232 | |||
235 | /*----------------------------------------------*\ | 233 | /*----------------------------------------------*\ | |
236 | | REDUCTION PHASE | | 234 | | REDUCTION PHASE | | |
237 | \*----------------------------------------------*/ | 235 | \*----------------------------------------------*/ | |
238 | 236 | |||
239 | /* | 237 | /* | |
240 | * Try to combine the statement on the top of the parse stack with the symbol | 238 | * Try to combine the statement on the top of the parse stack with the symbol | |
241 | * directly below it, replacing these two symbols with a single symbol. | 239 | * directly below it, replacing these two symbols with a single symbol. | |
242 | */ | 240 | */ | |
243 | static int | 241 | static int | |
244 | reduce_stmt(void) | 242 | reduce_stmt(void) | |
245 | { | 243 | { | |
246 | switch (ps.p_stack[ps.tos - 1]) { | 244 | switch (ps.p_stack[ps.tos - 1]) { | |
247 | 245 | |||
248 | case stmt: /* stmt stmt */ | 246 | case stmt: /* stmt stmt */ | |
249 | case stmt_list: /* stmt_list stmt */ | 247 | case stmt_list: /* stmt_list stmt */ | |
250 | ps.p_stack[--ps.tos] = stmt_list; | 248 | ps.p_stack[--ps.tos] = stmt_list; | |
251 | return true; | 249 | return true; | |
252 | 250 | |||
253 | case keyword_do: /* 'do' <stmt> */ | 251 | case keyword_do: /* 'do' <stmt> */ | |
254 | ps.p_stack[--ps.tos] = do_stmt; | 252 | ps.p_stack[--ps.tos] = do_stmt; | |
255 | ps.i_l_follow = ps.il[ps.tos]; | 253 | ps.i_l_follow = ps.il[ps.tos]; | |
256 | return true; | 254 | return true; | |
257 | 255 | |||
258 | case if_expr: /* 'if' '(' <expr> ')' <stmt> */ | 256 | case if_expr: /* 'if' '(' <expr> ')' <stmt> */ | |
259 | ps.p_stack[--ps.tos] = if_expr_stmt; | 257 | ps.p_stack[--ps.tos] = if_expr_stmt; | |
260 | int i = ps.tos - 1; | 258 | int i = ps.tos - 1; | |
261 | while (ps.p_stack[i] != stmt && | 259 | while (ps.p_stack[i] != stmt && | |
262 | ps.p_stack[i] != stmt_list && | 260 | ps.p_stack[i] != stmt_list && | |
263 | ps.p_stack[i] != lbrace) | 261 | ps.p_stack[i] != lbrace) | |
264 | --i; | 262 | --i; | |
265 | ps.i_l_follow = ps.il[i]; | 263 | ps.i_l_follow = ps.il[i]; | |
266 | /* | 264 | /* | |
267 | * for the time being, we will assume that there is no else on | 265 | * for the time being, we will assume that there is no else on | |
268 | * this if, and set the indentation level accordingly. If an | 266 | * this if, and set the indentation level accordingly. If an | |
269 | * else is scanned, it will be fixed up later | 267 | * else is scanned, it will be fixed up later | |
270 | */ | 268 | */ | |
271 | return true; | 269 | return true; | |
272 | 270 | |||
273 | case switch_expr: /* 'switch' '(' <expr> ')' <stmt> */ | 271 | case switch_expr: /* 'switch' '(' <expr> ')' <stmt> */ | |
274 | case_ind = ps.cstk[ps.tos - 1]; | 272 | case_ind = ps.cstk[ps.tos - 1]; | |
275 | /* FALLTHROUGH */ | 273 | /* FALLTHROUGH */ | |
276 | case decl: /* finish of a declaration */ | 274 | case decl: /* finish of a declaration */ | |
277 | case if_expr_stmt_else: /* 'if' '(' <expr> ')' <stmt> 'else' <stmt> */ | 275 | case if_expr_stmt_else: /* 'if' '(' <expr> ')' <stmt> 'else' <stmt> */ | |
278 | case for_exprs: /* 'for' '(' ... ')' <stmt> */ | 276 | case for_exprs: /* 'for' '(' ... ')' <stmt> */ | |
279 | case while_expr: /* 'while' '(' <expr> ')' <stmt> */ | 277 | case while_expr: /* 'while' '(' <expr> ')' <stmt> */ | |
280 | ps.p_stack[--ps.tos] = stmt; | 278 | ps.p_stack[--ps.tos] = stmt; | |
281 | ps.i_l_follow = ps.il[ps.tos]; | 279 | ps.i_l_follow = ps.il[ps.tos]; | |
282 | return true; | 280 | return true; | |
283 | 281 | |||
284 | default: /* <anything else> <stmt> */ | 282 | default: /* <anything else> <stmt> */ | |
285 | return false; | 283 | return false; | |
286 | } | 284 | } | |
287 | } | 285 | } | |
288 | 286 | |||
289 | /* | 287 | /* | |
290 | * Repeatedly try to reduce the top two symbols on the parse stack to a | 288 | * Repeatedly try to reduce the top two symbols on the parse stack to a | |
291 | * single symbol, until no more reductions are possible. | 289 | * single symbol, until no more reductions are possible. | |
292 | * | 290 | * | |
293 | * On each reduction, ps.i_l_follow (the indentation for the following line) | 291 | * On each reduction, ps.i_l_follow (the indentation for the following line) | |
294 | * is set to the indentation level associated with the old TOS. | 292 | * is set to the indentation level associated with the old TOS. | |
295 | */ | 293 | */ | |
296 | static void | 294 | static void | |
297 | reduce(void) | 295 | reduce(void) | |
298 | { | 296 | { | |
299 | again: | 297 | again: | |
300 | if (ps.p_stack[ps.tos] == stmt) { | 298 | if (ps.p_stack[ps.tos] == stmt) { | |
301 | if (reduce_stmt()) | 299 | if (reduce_stmt()) | |
302 | goto again; | 300 | goto again; | |
303 | } else if (ps.p_stack[ps.tos] == while_expr) { | 301 | } else if (ps.p_stack[ps.tos] == while_expr) { | |
304 | if (ps.p_stack[ps.tos - 1] == do_stmt) { | 302 | if (ps.p_stack[ps.tos - 1] == do_stmt) { | |
305 | ps.tos -= 2; | 303 | ps.tos -= 2; | |
306 | goto again; | 304 | goto again; | |
307 | } | 305 | } | |
308 | } | 306 | } | |
309 | } | 307 | } |