indent: fix lint warnings No functional change.diff -r1.10 -r1.11 src/usr.bin/indent/Makefile
(rillig)
--- src/usr.bin/indent/Makefile 2021/03/12 19:11:29 1.10
+++ src/usr.bin/indent/Makefile 2021/03/14 00:22:16 1.11
@@ -1,10 +1,13 @@ | @@ -1,10 +1,13 @@ | |||
1 | # $NetBSD: Makefile,v 1.10 2021/03/12 19:11:29 rillig Exp $ | 1 | # $NetBSD: Makefile,v 1.11 2021/03/14 00:22:16 rillig Exp $ | |
2 | # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 | 2 | # from: @(#)Makefile 8.1 (Berkeley) 6/6/93 | |
3 | 3 | |||
4 | PROG= indent | 4 | PROG= indent | |
5 | SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c | 5 | SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c | |
6 | 6 | |||
7 | CPPFLAGS+= ${DEBUG:D-Ddebug} | 7 | CPPFLAGS+= ${DEBUG:D-Ddebug} | |
8 | LINTFLAGS+= -e | 8 | LINTFLAGS+= -e -w | |
9 | ||||
10 | # bug in lint; see tests/usr.bin/lint/lint1/msg_168.c | |||
11 | LINTFLAGS.lexi.c+= -X 168 | |||
9 | 12 | |||
10 | .include <bsd.prog.mk> | 13 | .include <bsd.prog.mk> |
--- src/usr.bin/indent/args.c 2021/03/13 13:51:08 1.21
+++ src/usr.bin/indent/args.c 2021/03/14 00:22:16 1.22
@@ -1,359 +1,360 @@ | @@ -1,359 +1,360 @@ | |||
1 | /* $NetBSD: args.c,v 1.21 2021/03/13 13:51:08 rillig Exp $ */ | 1 | /* $NetBSD: args.c,v 1.22 2021/03/14 00:22:16 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.21 2021/03/13 13:51:08 rillig Exp $"); | 49 | __RCSID("$NetBSD: args.c,v 1.22 2021/03/14 00:22:16 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_comment_column}, | 122 | {"cd", PRO_INT, 0, 0, &opt.decl_comment_column}, | |
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.comment_column}, | 127 | {"c", PRO_INT, 33, 0, &opt.comment_column}, | |
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.indent_size}, | 137 | {"i", PRO_INT, 8, 0, &opt.indent_size}, | |
138 | {"lc", PRO_INT, 0, 0, &opt.block_comment_max_line_length}, | 138 | {"lc", PRO_INT, 0, 0, &opt.block_comment_max_line_length}, | |
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_line_length}, | 142 | {"l", PRO_INT, 78, 0, &opt.max_line_length}, | |
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 | for (;;) { | |
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 = (int)(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 | } else if (i == EOF) | 237 | } else if (i == EOF) | |
238 | return; | 238 | return; | |
239 | } | 239 | } | |
240 | } | 240 | } | |
241 | 241 | |||
242 | static const char * | 242 | static const char * | |
243 | eqin(const char *s1, const char *s2) | 243 | eqin(const char *s1, const char *s2) | |
244 | { | 244 | { | |
245 | while (*s1) { | 245 | while (*s1) { | |
246 | if (*s1++ != *s2++) | 246 | if (*s1++ != *s2++) | |
247 | return NULL; | 247 | return NULL; | |
248 | } | 248 | } | |
249 | return s2; | 249 | return s2; | |
250 | } | 250 | } | |
251 | 251 | |||
252 | /* | 252 | /* | |
253 | * Set the defaults. | 253 | * Set the defaults. | |
254 | */ | 254 | */ | |
255 | void | 255 | void | |
256 | set_defaults(void) | 256 | set_defaults(void) | |
257 | { | 257 | { | |
258 | /* | 258 | /* | |
259 | * 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 | |
260 | * table: | 260 | * table: | |
261 | */ | 261 | */ | |
262 | opt.case_indent = 0.0F; /* -cli0.0 */ | 262 | opt.case_indent = 0.0F; /* -cli0.0 */ | |
263 | 263 | |||
264 | for (const struct pro *p = pro; p->p_name; p++) | 264 | for (const struct pro *p = pro; p->p_name; p++) | |
265 | if (p->p_type != PRO_SPECIAL) | 265 | if (p->p_type != PRO_SPECIAL) | |
266 | *p->p_obj = p->p_default; | 266 | *p->p_obj = p->p_default; | |
267 | } | 267 | } | |
268 | 268 | |||
269 | void | 269 | void | |
270 | set_option(char *arg) | 270 | set_option(char *arg) | |
271 | { | 271 | { | |
272 | const struct pro *p; | 272 | const struct pro *p; | |
273 | const char *param_start; | 273 | const char *param_start; | |
274 | 274 | |||
275 | arg++; /* ignore leading "-" */ | 275 | arg++; /* ignore leading "-" */ | |
276 | for (p = pro; p->p_name; p++) | 276 | for (p = pro; p->p_name; p++) | |
277 | 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) | |
278 | goto found; | 278 | goto found; | |
279 | errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); | 279 | errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1); | |
280 | found: | 280 | found: | |
281 | switch (p->p_type) { | 281 | switch (p->p_type) { | |
282 | 282 | |||
283 | case PRO_SPECIAL: | 283 | case PRO_SPECIAL: | |
284 | switch (p->p_special) { | 284 | switch (p->p_special) { | |
285 | 285 | |||
286 | case IGN: | 286 | case IGN: | |
287 | break; | 287 | break; | |
288 | 288 | |||
289 | case CLI: | 289 | case CLI: | |
290 | if (*param_start == 0) | 290 | if (*param_start == 0) | |
291 | goto need_param; | 291 | goto need_param; | |
292 | opt.case_indent = atof(param_start); | 292 | opt.case_indent = atof(param_start); | |
293 | break; | 293 | break; | |
294 | 294 | |||
295 | case STDIN: | 295 | case STDIN: | |
296 | if (input == NULL) | 296 | if (input == NULL) | |
297 | input = stdin; | 297 | input = stdin; | |
298 | if (output == NULL) | 298 | if (output == NULL) | |
299 | output = stdout; | 299 | output = stdout; | |
300 | break; | 300 | break; | |
301 | 301 | |||
302 | case KEY: | 302 | case KEY: | |
303 | if (*param_start == 0) | 303 | if (*param_start == 0) | |
304 | goto need_param; | 304 | goto need_param; | |
305 | add_typename(param_start); | 305 | add_typename(param_start); | |
306 | break; | 306 | break; | |
307 | 307 | |||
308 | case KEY_FILE: | 308 | case KEY_FILE: | |
309 | if (*param_start == 0) | 309 | if (*param_start == 0) | |
310 | goto need_param; | 310 | goto need_param; | |
311 | add_typedefs_from_file(param_start); | 311 | add_typedefs_from_file(param_start); | |
312 | break; | 312 | break; | |
313 | 313 | |||
314 | case VERSION: | 314 | case VERSION: | |
315 | printf("FreeBSD indent %s\n", INDENT_VERSION); | 315 | printf("FreeBSD indent %s\n", INDENT_VERSION); | |
316 | exit(0); | 316 | exit(0); | |
317 | /*NOTREACHED*/ | |||
317 | 318 | |||
318 | default: | 319 | default: | |
319 | errx(1, "set_option: internal error: p_special %d", p->p_special); | 320 | errx(1, "set_option: internal error: p_special %d", p->p_special); | |
320 | } | 321 | } | |
321 | break; | 322 | break; | |
322 | 323 | |||
323 | case PRO_BOOL: | 324 | case PRO_BOOL: | |
324 | if (p->p_special == OFF) | 325 | if (p->p_special == OFF) | |
325 | *p->p_obj = false; | 326 | *p->p_obj = false; | |
326 | else | 327 | else | |
327 | *p->p_obj = true; | 328 | *p->p_obj = true; | |
328 | break; | 329 | break; | |
329 | 330 | |||
330 | case PRO_INT: | 331 | case PRO_INT: | |
331 | if (!isdigit((unsigned char)*param_start)) { | 332 | if (!isdigit((unsigned char)*param_start)) { | |
332 | need_param: | 333 | need_param: | |
333 | errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name); | 334 | errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name); | |
334 | } | 335 | } | |
335 | *p->p_obj = atoi(param_start); | 336 | *p->p_obj = atoi(param_start); | |
336 | break; | 337 | break; | |
337 | 338 | |||
338 | default: | 339 | default: | |
339 | errx(1, "set_option: internal error: p_type %d", p->p_type); | 340 | errx(1, "set_option: internal error: p_type %d", p->p_type); | |
340 | } | 341 | } | |
341 | } | 342 | } | |
342 | 343 | |||
343 | void | 344 | void | |
344 | add_typedefs_from_file(const char *str) | 345 | add_typedefs_from_file(const char *str) | |
345 | { | 346 | { | |
346 | FILE *file; | 347 | FILE *file; | |
347 | char line[BUFSIZ]; | 348 | char line[BUFSIZ]; | |
348 | 349 | |||
349 | if ((file = fopen(str, "r")) == NULL) { | 350 | if ((file = fopen(str, "r")) == NULL) { | |
350 | fprintf(stderr, "indent: cannot open file %s\n", str); | 351 | fprintf(stderr, "indent: cannot open file %s\n", str); | |
351 | exit(1); | 352 | exit(1); | |
352 | } | 353 | } | |
353 | while ((fgets(line, BUFSIZ, file)) != NULL) { | 354 | while ((fgets(line, BUFSIZ, file)) != NULL) { | |
354 | /* Remove trailing whitespace */ | 355 | /* Remove trailing whitespace */ | |
355 | line[strcspn(line, " \t\n\r")] = '\0'; | 356 | line[strcspn(line, " \t\n\r")] = '\0'; | |
356 | add_typename(line); | 357 | add_typename(line); | |
357 | } | 358 | } | |
358 | fclose(file); | 359 | fclose(file); | |
359 | } | 360 | } |
--- src/usr.bin/indent/indent.c 2021/03/13 18:46:39 1.58
+++ src/usr.bin/indent/indent.c 2021/03/14 00:22:16 1.59
@@ -1,1598 +1,1599 @@ | @@ -1,1598 +1,1599 @@ | |||
1 | /* $NetBSD: indent.c,v 1.58 2021/03/13 18:46:39 rillig Exp $ */ | 1 | /* $NetBSD: indent.c,v 1.59 2021/03/14 00:22:16 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.58 2021/03/13 18:46:39 rillig Exp $"); | 49 | __RCSID("$NetBSD: indent.c,v 1.59 2021/03/14 00:22:16 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 | break; | |||
209 | case form_feed: | 210 | case form_feed: | |
210 | break; | 211 | break; | |
211 | case comment: | 212 | case comment: | |
212 | if (sc_end == NULL) { | 213 | if (sc_end == NULL) { | |
213 | /* | 214 | /* | |
214 | * Copy everything from the start of the line, because | 215 | * Copy everything from the start of the line, because | |
215 | * process_comment() will use that to calculate original | 216 | * process_comment() will use that to calculate original | |
216 | * indentation of a boxed comment. | 217 | * indentation of a boxed comment. | |
217 | */ | 218 | */ | |
218 | memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4); | 219 | memcpy(sc_buf, in_buffer, (size_t)(buf_ptr - in_buffer) - 4); | |
219 | save_com = sc_buf + (buf_ptr - in_buffer - 4); | 220 | save_com = sc_buf + (buf_ptr - in_buffer - 4); | |
220 | save_com[0] = save_com[1] = ' '; | 221 | save_com[0] = save_com[1] = ' '; | |
221 | sc_end = &save_com[2]; | 222 | sc_end = &save_com[2]; | |
222 | } | 223 | } | |
223 | *inout_comment_buffered = true; | 224 | *inout_comment_buffered = true; | |
224 | *sc_end++ = '/'; /* copy in start of comment */ | 225 | *sc_end++ = '/'; /* copy in start of comment */ | |
225 | *sc_end++ = '*'; | 226 | *sc_end++ = '*'; | |
226 | for (;;) { /* loop until the end of the comment */ | 227 | for (;;) { /* loop until the end of the comment */ | |
227 | *sc_end = *buf_ptr++; | 228 | *sc_end = *buf_ptr++; | |
228 | if (buf_ptr >= buf_end) | 229 | if (buf_ptr >= buf_end) | |
229 | fill_buffer(); | 230 | fill_buffer(); | |
230 | if (*sc_end++ == '*' && *buf_ptr == '/') | 231 | if (*sc_end++ == '*' && *buf_ptr == '/') | |
231 | break; /* we are at end of comment */ | 232 | break; /* we are at end of comment */ | |
232 | if (sc_end >= &save_com[sc_size]) { /* check for temp buffer | 233 | if (sc_end >= &save_com[sc_size]) { /* check for temp buffer | |
233 | * overflow */ | 234 | * overflow */ | |
234 | diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); | 235 | diag(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever"); | |
235 | fflush(output); | 236 | fflush(output); | |
236 | exit(1); | 237 | exit(1); | |
237 | } | 238 | } | |
238 | } | 239 | } | |
239 | *sc_end++ = '/'; /* add ending slash */ | 240 | *sc_end++ = '/'; /* add ending slash */ | |
240 | if (++buf_ptr >= buf_end) /* get past / in buffer */ | 241 | if (++buf_ptr >= buf_end) /* get past / in buffer */ | |
241 | fill_buffer(); | 242 | fill_buffer(); | |
242 | break; | 243 | break; | |
243 | case lbrace: | 244 | case lbrace: | |
244 | /* | 245 | /* | |
245 | * Put KNF-style lbraces before the buffered up tokens and | 246 | * Put KNF-style lbraces before the buffered up tokens and | |
246 | * jump out of this loop in order to avoid copying the token | 247 | * jump out of this loop in order to avoid copying the token | |
247 | * again under the default case of the switch below. | 248 | * again under the default case of the switch below. | |
248 | */ | 249 | */ | |
249 | if (sc_end != NULL && opt.btype_2) { | 250 | if (sc_end != NULL && opt.btype_2) { | |
250 | save_com[0] = '{'; | 251 | save_com[0] = '{'; | |
251 | /* | 252 | /* | |
252 | * Originally the lbrace may have been alone on its own | 253 | * Originally the lbrace may have been alone on its own | |
253 | * line, but it will be moved into "the else's line", so | 254 | * line, but it will be moved into "the else's line", so | |
254 | * if there was a newline resulting from the "{" before, | 255 | * if there was a newline resulting from the "{" before, | |
255 | * it must be scanned now and ignored. | 256 | * it must be scanned now and ignored. | |
256 | */ | 257 | */ | |
257 | while (isspace((unsigned char)*buf_ptr)) { | 258 | while (isspace((unsigned char)*buf_ptr)) { | |
258 | if (++buf_ptr >= buf_end) | 259 | if (++buf_ptr >= buf_end) | |
259 | fill_buffer(); | 260 | fill_buffer(); | |
260 | if (*buf_ptr == '\n') | 261 | if (*buf_ptr == '\n') | |
261 | break; | 262 | break; | |
262 | } | 263 | } | |
263 | goto sw_buffer; | 264 | goto sw_buffer; | |
264 | } | 265 | } | |
265 | /* FALLTHROUGH */ | 266 | /* FALLTHROUGH */ | |
266 | default: /* it is the start of a normal statement */ | 267 | default: /* it is the start of a normal statement */ | |
267 | { | 268 | { | |
268 | int remove_newlines; | 269 | int remove_newlines; | |
269 | 270 | |||
270 | remove_newlines = | 271 | remove_newlines = | |
271 | /* "} else" */ | 272 | /* "} else" */ | |
272 | (*inout_type_code == keyword_do_else && *token == 'e' && | 273 | (*inout_type_code == keyword_do_else && *token == 'e' && | |
273 | e_code != s_code && e_code[-1] == '}') | 274 | e_code != s_code && e_code[-1] == '}') | |
274 | /* "else if" */ | 275 | /* "else if" */ | |
275 | || (*inout_type_code == keyword_for_if_while && | 276 | || (*inout_type_code == keyword_for_if_while && | |
276 | *token == 'i' && *inout_last_else && opt.else_if); | 277 | *token == 'i' && *inout_last_else && opt.else_if); | |
277 | if (remove_newlines) | 278 | if (remove_newlines) | |
278 | *inout_force_nl = false; | 279 | *inout_force_nl = false; | |
279 | if (sc_end == NULL) { /* ignore buffering if | 280 | if (sc_end == NULL) { /* ignore buffering if | |
280 | * comment wasn't saved up */ | 281 | * comment wasn't saved up */ | |
281 | ps.search_brace = false; | 282 | ps.search_brace = false; | |
282 | return; | 283 | return; | |
283 | } | 284 | } | |
284 | while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) { | 285 | while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) { | |
285 | sc_end--; | 286 | sc_end--; | |
286 | } | 287 | } | |
287 | if (opt.swallow_optional_blanklines || | 288 | if (opt.swallow_optional_blanklines || | |
288 | (!*inout_comment_buffered && remove_newlines)) { | 289 | (!*inout_comment_buffered && remove_newlines)) { | |
289 | *inout_force_nl = !remove_newlines; | 290 | *inout_force_nl = !remove_newlines; | |
290 | while (sc_end > save_com && sc_end[-1] == '\n') { | 291 | while (sc_end > save_com && sc_end[-1] == '\n') { | |
291 | sc_end--; | 292 | sc_end--; | |
292 | } | 293 | } | |
293 | } | 294 | } | |
294 | if (*inout_force_nl) { /* if we should insert a nl here, put | 295 | if (*inout_force_nl) { /* if we should insert a nl here, put | |
295 | * it into the buffer */ | 296 | * it into the buffer */ | |
296 | *inout_force_nl = false; | 297 | *inout_force_nl = false; | |
297 | --line_no; /* this will be re-increased when the | 298 | --line_no; /* this will be re-increased when the | |
298 | * newline is read from the buffer */ | 299 | * newline is read from the buffer */ | |
299 | *sc_end++ = '\n'; | 300 | *sc_end++ = '\n'; | |
300 | *sc_end++ = ' '; | 301 | *sc_end++ = ' '; | |
301 | if (opt.verbose) /* print error msg if the line was | 302 | if (opt.verbose) /* print error msg if the line was | |
302 | * not already broken */ | 303 | * not already broken */ | |
303 | diag(0, "Line broken"); | 304 | diag(0, "Line broken"); | |
304 | } | 305 | } | |
305 | for (const char *t_ptr = token; *t_ptr; ++t_ptr) | 306 | for (const char *t_ptr = token; *t_ptr; ++t_ptr) | |
306 | *sc_end++ = *t_ptr; | 307 | *sc_end++ = *t_ptr; | |
307 | 308 | |||
308 | sw_buffer: | 309 | sw_buffer: | |
309 | ps.search_brace = false; /* stop looking for start of stmt */ | 310 | ps.search_brace = false; /* stop looking for start of stmt */ | |
310 | bp_save = buf_ptr; /* save current input buffer */ | 311 | bp_save = buf_ptr; /* save current input buffer */ | |
311 | be_save = buf_end; | 312 | be_save = buf_end; | |
312 | buf_ptr = save_com; /* fix so that subsequent calls to | 313 | buf_ptr = save_com; /* fix so that subsequent calls to | |
313 | * lexi will take tokens out of save_com */ | 314 | * lexi will take tokens out of save_com */ | |
314 | *sc_end++ = ' '; /* add trailing blank, just in case */ | 315 | *sc_end++ = ' '; /* add trailing blank, just in case */ | |
315 | buf_end = sc_end; | 316 | buf_end = sc_end; | |
316 | sc_end = NULL; | 317 | sc_end = NULL; | |
317 | debug_println("switched buf_ptr to save_com"); | 318 | debug_println("switched buf_ptr to save_com"); | |
318 | break; | 319 | break; | |
319 | } | 320 | } | |
320 | } /* end of switch */ | 321 | } /* end of switch */ | |
321 | /* | 322 | /* | |
322 | * We must make this check, just in case there was an unexpected | 323 | * We must make this check, just in case there was an unexpected | |
323 | * EOF. | 324 | * EOF. | |
324 | */ | 325 | */ | |
325 | if (*inout_type_code != end_of_file) { | 326 | if (*inout_type_code != end_of_file) { | |
326 | /* | 327 | /* | |
327 | * The only intended purpose of calling lexi() below is to | 328 | * The only intended purpose of calling lexi() below is to | |
328 | * categorize the next token in order to decide whether to | 329 | * categorize the next token in order to decide whether to | |
329 | * continue buffering forthcoming tokens. Once the buffering | 330 | * continue buffering forthcoming tokens. Once the buffering | |
330 | * is over, lexi() will be called again elsewhere on all of | 331 | * is over, lexi() will be called again elsewhere on all of | |
331 | * the tokens - this time for normal processing. | 332 | * the tokens - this time for normal processing. | |
332 | * | 333 | * | |
333 | * Calling it for this purpose is a bug, because lexi() also | 334 | * Calling it for this purpose is a bug, because lexi() also | |
334 | * changes the parser state and discards leading whitespace, | 335 | * changes the parser state and discards leading whitespace, | |
335 | * which is needed mostly for comment-related considerations. | 336 | * which is needed mostly for comment-related considerations. | |
336 | * | 337 | * | |
337 | * Work around the former problem by giving lexi() a copy of | 338 | * Work around the former problem by giving lexi() a copy of | |
338 | * the current parser state and discard it if the call turned | 339 | * the current parser state and discard it if the call turned | |
339 | * out to be just a look ahead. | 340 | * out to be just a look ahead. | |
340 | * | 341 | * | |
341 | * Work around the latter problem by copying all whitespace | 342 | * Work around the latter problem by copying all whitespace | |
342 | * characters into the buffer so that the later lexi() call | 343 | * characters into the buffer so that the later lexi() call | |
343 | * will read them. | 344 | * will read them. | |
344 | */ | 345 | */ | |
345 | if (sc_end != NULL) { | 346 | if (sc_end != NULL) { | |
346 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | 347 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | |
347 | *sc_end++ = *buf_ptr++; | 348 | *sc_end++ = *buf_ptr++; | |
348 | if (sc_end >= &save_com[sc_size]) { | 349 | if (sc_end >= &save_com[sc_size]) { | |
349 | errx(1, "input too long"); | 350 | errx(1, "input too long"); | |
350 | } | 351 | } | |
351 | } | 352 | } | |
352 | if (buf_ptr >= buf_end) { | 353 | if (buf_ptr >= buf_end) { | |
353 | fill_buffer(); | 354 | fill_buffer(); | |
354 | } | 355 | } | |
355 | } | 356 | } | |
356 | 357 | |||
357 | struct parser_state transient_state; | 358 | struct parser_state transient_state; | |
358 | transient_state = ps; | 359 | transient_state = ps; | |
359 | *inout_type_code = lexi(&transient_state); /* read another token */ | 360 | *inout_type_code = lexi(&transient_state); /* read another token */ | |
360 | if (*inout_type_code != newline && *inout_type_code != form_feed && | 361 | if (*inout_type_code != newline && *inout_type_code != form_feed && | |
361 | *inout_type_code != comment && !transient_state.search_brace) { | 362 | *inout_type_code != comment && !transient_state.search_brace) { | |
362 | ps = transient_state; | 363 | ps = transient_state; | |
363 | } | 364 | } | |
364 | } | 365 | } | |
365 | } | 366 | } | |
366 | 367 | |||
367 | *inout_last_else = 0; | 368 | *inout_last_else = 0; | |
368 | } | 369 | } | |
369 | 370 | |||
370 | static void | 371 | static void | |
371 | main_init_globals(void) | 372 | main_init_globals(void) | |
372 | { | 373 | { | |
373 | found_err = 0; | 374 | found_err = 0; | |
374 | 375 | |||
375 | ps.p_stack[0] = stmt; /* this is the parser's stack */ | 376 | ps.p_stack[0] = stmt; /* this is the parser's stack */ | |
376 | ps.last_nl = true; /* this is true if the last thing scanned was | 377 | ps.last_nl = true; /* this is true if the last thing scanned was | |
377 | * a newline */ | 378 | * a newline */ | |
378 | ps.last_token = semicolon; | 379 | ps.last_token = semicolon; | |
379 | combuf = malloc(bufsize); | 380 | combuf = malloc(bufsize); | |
380 | if (combuf == NULL) | 381 | if (combuf == NULL) | |
381 | err(1, NULL); | 382 | err(1, NULL); | |
382 | labbuf = malloc(bufsize); | 383 | labbuf = malloc(bufsize); | |
383 | if (labbuf == NULL) | 384 | if (labbuf == NULL) | |
384 | err(1, NULL); | 385 | err(1, NULL); | |
385 | codebuf = malloc(bufsize); | 386 | codebuf = malloc(bufsize); | |
386 | if (codebuf == NULL) | 387 | if (codebuf == NULL) | |
387 | err(1, NULL); | 388 | err(1, NULL); | |
388 | tokenbuf = malloc(bufsize); | 389 | tokenbuf = malloc(bufsize); | |
389 | if (tokenbuf == NULL) | 390 | if (tokenbuf == NULL) | |
390 | err(1, NULL); | 391 | err(1, NULL); | |
391 | alloc_typenames(); | 392 | alloc_typenames(); | |
392 | init_constant_tt(); | 393 | init_constant_tt(); | |
393 | l_com = combuf + bufsize - 5; | 394 | l_com = combuf + bufsize - 5; | |
394 | l_lab = labbuf + bufsize - 5; | 395 | l_lab = labbuf + bufsize - 5; | |
395 | l_code = codebuf + bufsize - 5; | 396 | l_code = codebuf + bufsize - 5; | |
396 | l_token = tokenbuf + bufsize - 5; | 397 | l_token = tokenbuf + bufsize - 5; | |
397 | combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and | 398 | combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and | |
398 | * comment buffers */ | 399 | * comment buffers */ | |
399 | combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; | 400 | combuf[1] = codebuf[1] = labbuf[1] = tokenbuf[1] = '\0'; | |
400 | opt.else_if = 1; /* Default else-if special processing to on */ | 401 | opt.else_if = 1; /* Default else-if special processing to on */ | |
401 | s_lab = e_lab = labbuf + 1; | 402 | s_lab = e_lab = labbuf + 1; | |
402 | s_code = e_code = codebuf + 1; | 403 | s_code = e_code = codebuf + 1; | |
403 | s_com = e_com = combuf + 1; | 404 | s_com = e_com = combuf + 1; | |
404 | s_token = e_token = tokenbuf + 1; | 405 | s_token = e_token = tokenbuf + 1; | |
405 | 406 | |||
406 | in_buffer = malloc(10); | 407 | in_buffer = malloc(10); | |
407 | if (in_buffer == NULL) | 408 | if (in_buffer == NULL) | |
408 | err(1, NULL); | 409 | err(1, NULL); | |
409 | in_buffer_limit = in_buffer + 8; | 410 | in_buffer_limit = in_buffer + 8; | |
410 | buf_ptr = buf_end = in_buffer; | 411 | buf_ptr = buf_end = in_buffer; | |
411 | line_no = 1; | 412 | line_no = 1; | |
412 | had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; | 413 | had_eof = ps.in_decl = ps.decl_on_line = break_comma = false; | |
413 | ps.in_or_st = false; | 414 | ps.in_or_st = false; | |
414 | ps.bl_line = true; | 415 | ps.bl_line = true; | |
415 | ps.want_blank = ps.in_stmt = ps.ind_stmt = false; | 416 | ps.want_blank = ps.in_stmt = ps.ind_stmt = false; | |
416 | 417 | |||
417 | ps.pcase = false; | 418 | ps.pcase = false; | |
418 | sc_end = NULL; | 419 | sc_end = NULL; | |
419 | bp_save = NULL; | 420 | bp_save = NULL; | |
420 | be_save = NULL; | 421 | be_save = NULL; | |
421 | 422 | |||
422 | output = NULL; | 423 | output = NULL; | |
423 | 424 | |||
424 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | 425 | const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); | |
425 | if (suffix != NULL) | 426 | if (suffix != NULL) | |
426 | simple_backup_suffix = suffix; | 427 | simple_backup_suffix = suffix; | |
427 | } | 428 | } | |
428 | 429 | |||
429 | static void | 430 | static void | |
430 | main_parse_command_line(int argc, char **argv) | 431 | main_parse_command_line(int argc, char **argv) | |
431 | { | 432 | { | |
432 | int i; | 433 | int i; | |
433 | const char *profile_name = NULL; | 434 | const char *profile_name = NULL; | |
434 | 435 | |||
435 | #if 0 | 436 | #if 0 | |
436 | max_line_length = 78; /* -l78 */ | 437 | max_line_length = 78; /* -l78 */ | |
437 | lineup_to_parens = 1; /* -lp */ | 438 | lineup_to_parens = 1; /* -lp */ | |
438 | lineup_to_parens_always = 0; /* -nlpl */ | 439 | lineup_to_parens_always = 0; /* -nlpl */ | |
439 | ps.ljust_decl = 0; /* -ndj */ | 440 | ps.ljust_decl = 0; /* -ndj */ | |
440 | ps.com_ind = 33; /* -c33 */ | 441 | ps.com_ind = 33; /* -c33 */ | |
441 | star_comment_cont = 1; /* -sc */ | 442 | star_comment_cont = 1; /* -sc */ | |
442 | ps.ind_size = 8; /* -i8 */ | 443 | ps.ind_size = 8; /* -i8 */ | |
443 | verbose = 0; | 444 | verbose = 0; | |
444 | ps.decl_indent = 16; /* -di16 */ | 445 | ps.decl_indent = 16; /* -di16 */ | |
445 | ps.local_decl_indent = -1; /* if this is not set to some nonnegative value | 446 | ps.local_decl_indent = -1; /* if this is not set to some nonnegative value | |
446 | * by an arg, we will set this equal to | 447 | * by an arg, we will set this equal to | |
447 | * ps.decl_ind */ | 448 | * ps.decl_ind */ | |
448 | ps.indent_parameters = 1; /* -ip */ | 449 | ps.indent_parameters = 1; /* -ip */ | |
449 | ps.decl_com_ind = 0; /* if this is not set to some positive value | 450 | ps.decl_com_ind = 0; /* if this is not set to some positive value | |
450 | * by an arg, we will set this equal to | 451 | * by an arg, we will set this equal to | |
451 | * ps.com_ind */ | 452 | * ps.com_ind */ | |
452 | btype_2 = 1; /* -br */ | 453 | btype_2 = 1; /* -br */ | |
453 | cuddle_else = 1; /* -ce */ | 454 | cuddle_else = 1; /* -ce */ | |
454 | ps.unindent_displace = 0; /* -d0 */ | 455 | ps.unindent_displace = 0; /* -d0 */ | |
455 | ps.case_indent = 0; /* -cli0 */ | 456 | ps.case_indent = 0; /* -cli0 */ | |
456 | format_block_comments = 1; /* -fcb */ | 457 | format_block_comments = 1; /* -fcb */ | |
457 | format_col1_comments = 1; /* -fc1 */ | 458 | format_col1_comments = 1; /* -fc1 */ | |
458 | procnames_start_line = 1; /* -psl */ | 459 | procnames_start_line = 1; /* -psl */ | |
459 | proc_calls_space = 0; /* -npcs */ | 460 | proc_calls_space = 0; /* -npcs */ | |
460 | comment_delimiter_on_blankline = 1; /* -cdb */ | 461 | comment_delimiter_on_blankline = 1; /* -cdb */ | |
461 | ps.leave_comma = 1; /* -nbc */ | 462 | ps.leave_comma = 1; /* -nbc */ | |
462 | #endif | 463 | #endif | |
463 | 464 | |||
464 | for (i = 1; i < argc; ++i) | 465 | for (i = 1; i < argc; ++i) | |
465 | if (strcmp(argv[i], "-npro") == 0) | 466 | if (strcmp(argv[i], "-npro") == 0) | |
466 | break; | 467 | break; | |
467 | else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') | 468 | else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0') | |
468 | profile_name = argv[i]; /* non-empty -P (set profile) */ | 469 | profile_name = argv[i]; /* non-empty -P (set profile) */ | |
469 | set_defaults(); | 470 | set_defaults(); | |
470 | if (i >= argc) | 471 | if (i >= argc) | |
471 | set_profile(profile_name); | 472 | set_profile(profile_name); | |
472 | 473 | |||
473 | for (i = 1; i < argc; ++i) { | 474 | for (i = 1; i < argc; ++i) { | |
474 | 475 | |||
475 | /* | 476 | /* | |
476 | * look thru args (if any) for changes to defaults | 477 | * look thru args (if any) for changes to defaults | |
477 | */ | 478 | */ | |
478 | if (argv[i][0] != '-') {/* no flag on parameter */ | 479 | if (argv[i][0] != '-') {/* no flag on parameter */ | |
479 | if (input == NULL) { /* we must have the input file */ | 480 | if (input == NULL) { /* we must have the input file */ | |
480 | in_name = argv[i]; /* remember name of input file */ | 481 | in_name = argv[i]; /* remember name of input file */ | |
481 | input = fopen(in_name, "r"); | 482 | input = fopen(in_name, "r"); | |
482 | if (input == NULL) /* check for open error */ | 483 | if (input == NULL) /* check for open error */ | |
483 | err(1, "%s", in_name); | 484 | err(1, "%s", in_name); | |
484 | continue; | 485 | continue; | |
485 | } else if (output == NULL) { /* we have the output file */ | 486 | } else if (output == NULL) { /* we have the output file */ | |
486 | out_name = argv[i]; /* remember name of output file */ | 487 | out_name = argv[i]; /* remember name of output file */ | |
487 | if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite | 488 | if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite | |
488 | * the file */ | 489 | * the file */ | |
489 | errx(1, "input and output files must be different"); | 490 | errx(1, "input and output files must be different"); | |
490 | } | 491 | } | |
491 | output = fopen(out_name, "w"); | 492 | output = fopen(out_name, "w"); | |
492 | if (output == NULL) /* check for create error */ | 493 | if (output == NULL) /* check for create error */ | |
493 | err(1, "%s", out_name); | 494 | err(1, "%s", out_name); | |
494 | continue; | 495 | continue; | |
495 | } | 496 | } | |
496 | errx(1, "unknown parameter: %s", argv[i]); | 497 | errx(1, "unknown parameter: %s", argv[i]); | |
497 | } else | 498 | } else | |
498 | set_option(argv[i]); | 499 | set_option(argv[i]); | |
499 | } /* end of for */ | 500 | } /* end of for */ | |
500 | if (input == NULL) | 501 | if (input == NULL) | |
501 | input = stdin; | 502 | input = stdin; | |
502 | if (output == NULL) { | 503 | if (output == NULL) { | |
503 | if (input == stdin) | 504 | if (input == stdin) | |
504 | output = stdout; | 505 | output = stdout; | |
505 | else { | 506 | else { | |
506 | out_name = in_name; | 507 | out_name = in_name; | |
507 | bakcopy(); | 508 | bakcopy(); | |
508 | } | 509 | } | |
509 | } | 510 | } | |
510 | 511 | |||
511 | if (opt.comment_column <= 1) | 512 | if (opt.comment_column <= 1) | |
512 | opt.comment_column = 2; /* don't put normal comments before column 2 */ | 513 | opt.comment_column = 2; /* don't put normal comments before column 2 */ | |
513 | if (opt.block_comment_max_line_length <= 0) | 514 | if (opt.block_comment_max_line_length <= 0) | |
514 | opt.block_comment_max_line_length = opt.max_line_length; | 515 | opt.block_comment_max_line_length = opt.max_line_length; | |
515 | if (opt.local_decl_indent < 0) /* if not specified by user, set this */ | 516 | if (opt.local_decl_indent < 0) /* if not specified by user, set this */ | |
516 | opt.local_decl_indent = opt.decl_indent; | 517 | opt.local_decl_indent = opt.decl_indent; | |
517 | if (opt.decl_comment_column <= 0) /* if not specified by user, set this */ | 518 | if (opt.decl_comment_column <= 0) /* if not specified by user, set this */ | |
518 | opt.decl_comment_column = opt.ljust_decl | 519 | opt.decl_comment_column = opt.ljust_decl | |
519 | ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) | 520 | ? (opt.comment_column <= 10 ? 2 : opt.comment_column - 8) | |
520 | : opt.comment_column; | 521 | : opt.comment_column; | |
521 | if (opt.continuation_indent == 0) | 522 | if (opt.continuation_indent == 0) | |
522 | opt.continuation_indent = opt.indent_size; | 523 | opt.continuation_indent = opt.indent_size; | |
523 | } | 524 | } | |
524 | 525 | |||
525 | static void | 526 | static void | |
526 | main_prepare_parsing(void) | 527 | main_prepare_parsing(void) | |
527 | { | 528 | { | |
528 | fill_buffer(); /* get first batch of stuff into input buffer */ | 529 | fill_buffer(); /* get first batch of stuff into input buffer */ | |
529 | 530 | |||
530 | parse(semicolon); | 531 | parse(semicolon); | |
531 | 532 | |||
532 | char *p = buf_ptr; | 533 | char *p = buf_ptr; | |
533 | int col = 1; | 534 | int col = 1; | |
534 | 535 | |||
535 | while (1) { | 536 | for (;;) { | |
536 | if (*p == ' ') | 537 | if (*p == ' ') | |
537 | col++; | 538 | col++; | |
538 | else if (*p == '\t') | 539 | else if (*p == '\t') | |
539 | col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; | 540 | col = opt.tabsize * (1 + (col - 1) / opt.tabsize) + 1; | |
540 | else | 541 | else | |
541 | break; | 542 | break; | |
542 | p++; | 543 | p++; | |
543 | } | 544 | } | |
544 | if (col > opt.indent_size) | 545 | if (col > opt.indent_size) | |
545 | ps.ind_level = ps.i_l_follow = col / opt.indent_size; | 546 | ps.ind_level = ps.i_l_follow = col / opt.indent_size; | |
546 | } | 547 | } | |
547 | 548 | |||
548 | static void | 549 | static void | |
549 | process_end_of_file(void) | 550 | process_end_of_file(void) | |
550 | { | 551 | { | |
551 | if (s_lab != e_lab || s_code != e_code || s_com != e_com) | 552 | if (s_lab != e_lab || s_code != e_code || s_com != e_com) | |
552 | dump_line(); | 553 | dump_line(); | |
553 | 554 | |||
554 | if (ps.tos > 1) /* check for balanced braces */ | 555 | if (ps.tos > 1) /* check for balanced braces */ | |
555 | diag(1, "Stuff missing from end of file"); | 556 | diag(1, "Stuff missing from end of file"); | |
556 | 557 | |||
557 | if (opt.verbose) { | 558 | if (opt.verbose) { | |
558 | printf("There were %d output lines and %d comments\n", | 559 | printf("There were %d output lines and %d comments\n", | |
559 | ps.out_lines, ps.out_coms); | 560 | ps.out_lines, ps.out_coms); | |
560 | printf("(Lines with comments)/(Lines with code): %6.3f\n", | 561 | printf("(Lines with comments)/(Lines with code): %6.3f\n", | |
561 | (1.0 * ps.com_lines) / code_lines); | 562 | (1.0 * ps.com_lines) / code_lines); | |
562 | } | 563 | } | |
563 | 564 | |||
564 | fflush(output); | 565 | fflush(output); | |
565 | exit(found_err); | 566 | exit(found_err); | |
566 | } | 567 | } | |
567 | 568 | |||
568 | static void | 569 | static void | |
569 | process_comment_in_code(token_type type_code, int *inout_force_nl) | 570 | process_comment_in_code(token_type type_code, int *inout_force_nl) | |
570 | { | 571 | { | |
571 | if (*inout_force_nl && | 572 | if (*inout_force_nl && | |
572 | type_code != semicolon && | 573 | type_code != semicolon && | |
573 | (type_code != lbrace || !opt.btype_2)) { | 574 | (type_code != lbrace || !opt.btype_2)) { | |
574 | 575 | |||
575 | /* we should force a broken line here */ | 576 | /* we should force a broken line here */ | |
576 | if (opt.verbose) | 577 | if (opt.verbose) | |
577 | diag(0, "Line broken"); | 578 | diag(0, "Line broken"); | |
578 | dump_line(); | 579 | dump_line(); | |
579 | ps.want_blank = false; /* dont insert blank at line start */ | 580 | ps.want_blank = false; /* dont insert blank at line start */ | |
580 | *inout_force_nl = false; | 581 | *inout_force_nl = false; | |
581 | } | 582 | } | |
582 | 583 | |||
583 | ps.in_stmt = true; /* turn on flag which causes an extra level of | 584 | ps.in_stmt = true; /* turn on flag which causes an extra level of | |
584 | * indentation. this is turned off by a ; or | 585 | * indentation. this is turned off by a ; or | |
585 | * '}' */ | 586 | * '}' */ | |
586 | if (s_com != e_com) { /* the turkey has embedded a comment | 587 | if (s_com != e_com) { /* the turkey has embedded a comment | |
587 | * in a line. fix it */ | 588 | * in a line. fix it */ | |
588 | int len = e_com - s_com; | 589 | size_t len = e_com - s_com; | |
589 | 590 | |||
590 | check_size_code(len + 3); | 591 | check_size_code(len + 3); | |
591 | *e_code++ = ' '; | 592 | *e_code++ = ' '; | |
592 | memcpy(e_code, s_com, len); | 593 | memcpy(e_code, s_com, len); | |
593 | e_code += len; | 594 | e_code += len; | |
594 | *e_code++ = ' '; | 595 | *e_code++ = ' '; | |
595 | *e_code = '\0'; /* null terminate code sect */ | 596 | *e_code = '\0'; /* null terminate code sect */ | |
596 | ps.want_blank = false; | 597 | ps.want_blank = false; | |
597 | e_com = s_com; | 598 | e_com = s_com; | |
598 | } | 599 | } | |
599 | } | 600 | } | |
600 | 601 | |||
601 | static void | 602 | static void | |
602 | process_form_feed(void) | 603 | process_form_feed(void) | |
603 | { | 604 | { | |
604 | ps.use_ff = true; /* a form feed is treated much like a newline */ | 605 | ps.use_ff = true; /* a form feed is treated much like a newline */ | |
605 | dump_line(); | 606 | dump_line(); | |
606 | ps.want_blank = false; | 607 | ps.want_blank = false; | |
607 | } | 608 | } | |
608 | 609 | |||
609 | static void | 610 | static void | |
610 | process_newline(void) | 611 | process_newline(void) | |
611 | { | 612 | { | |
612 | if (ps.last_token != comma || ps.p_l_follow > 0 | 613 | if (ps.last_token != comma || ps.p_l_follow > 0 | |
613 | || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { | 614 | || !opt.leave_comma || ps.block_init || !break_comma || s_com != e_com) { | |
614 | dump_line(); | 615 | dump_line(); | |
615 | ps.want_blank = false; | 616 | ps.want_blank = false; | |
616 | } | 617 | } | |
617 | ++line_no; /* keep track of input line number */ | 618 | ++line_no; /* keep track of input line number */ | |
618 | } | 619 | } | |
619 | 620 | |||
620 | static void | 621 | static void | |
621 | process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw) | 622 | process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw) | |
622 | { | 623 | { | |
623 | /* count parens to make Healy happy */ | 624 | /* count parens to make Healy happy */ | |
624 | if (++ps.p_l_follow == nitems(ps.paren_indents)) { | 625 | if (++ps.p_l_follow == nitems(ps.paren_indents)) { | |
625 | diag(0, "Reached internal limit of %zu unclosed parens", | 626 | diag(0, "Reached internal limit of %zu unclosed parens", | |
626 | nitems(ps.paren_indents)); | 627 | nitems(ps.paren_indents)); | |
627 | ps.p_l_follow--; | 628 | ps.p_l_follow--; | |
628 | } | 629 | } | |
629 | if (*token == '[') | 630 | if (*token == '[') | |
630 | /* not a function pointer declaration or a function call */; | 631 | /* not a function pointer declaration or a function call */; | |
631 | else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && | 632 | else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent && | |
632 | ps.procname[0] == '\0' && ps.paren_level == 0) { | 633 | ps.procname[0] == '\0' && ps.paren_level == 0) { | |
633 | /* function pointer declarations */ | 634 | /* function pointer declarations */ | |
634 | indent_declaration(dec_ind, tabs_to_var); | 635 | indent_declaration(dec_ind, tabs_to_var); | |
635 | ps.dumped_decl_indent = true; | 636 | ps.dumped_decl_indent = true; | |
636 | } else if (ps.want_blank && | 637 | } else if (ps.want_blank && | |
637 | ((ps.last_token != ident && ps.last_token != funcname) || | 638 | ((ps.last_token != ident && ps.last_token != funcname) || | |
638 | opt.proc_calls_space || | 639 | opt.proc_calls_space || | |
639 | (ps.keyword == rw_sizeof ? opt.Bill_Shannon : | 640 | (ps.keyword == rw_sizeof ? opt.Bill_Shannon : | |
640 | ps.keyword != rw_0 && ps.keyword != rw_offsetof))) | 641 | ps.keyword != rw_0 && ps.keyword != rw_offsetof))) | |
641 | *e_code++ = ' '; | 642 | *e_code++ = ' '; | |
642 | ps.want_blank = false; | 643 | ps.want_blank = false; | |
643 | *e_code++ = token[0]; | 644 | *e_code++ = token[0]; | |
644 | 645 | |||
645 | ps.paren_indents[ps.p_l_follow - 1] = | 646 | ps.paren_indents[ps.p_l_follow - 1] = | |
646 | indentation_after_range(0, s_code, e_code); | 647 | indentation_after_range(0, s_code, e_code); | |
647 | debug_println("paren_indent[%d] is now %d", | 648 | debug_println("paren_indent[%d] is now %d", | |
648 | ps.p_l_follow - 1, ps.paren_indents[ps.p_l_follow - 1]); | 649 | ps.p_l_follow - 1, ps.paren_indents[ps.p_l_follow - 1]); | |
649 | 650 | |||
650 | if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent | 651 | if (sp_sw && ps.p_l_follow == 1 && opt.extra_expression_indent | |
651 | && ps.paren_indents[0] < 2 * opt.indent_size) { | 652 | && ps.paren_indents[0] < 2 * opt.indent_size) { | |
652 | ps.paren_indents[0] = 2 * opt.indent_size; | 653 | ps.paren_indents[0] = 2 * opt.indent_size; | |
653 | debug_println("paren_indent[0] is now %d", ps.paren_indents[0]); | 654 | debug_println("paren_indent[0] is now %d", ps.paren_indents[0]); | |
654 | } | 655 | } | |
655 | if (ps.in_or_st && *token == '(' && ps.tos <= 2) { | 656 | if (ps.in_or_st && *token == '(' && ps.tos <= 2) { | |
656 | /* | 657 | /* | |
657 | * this is a kluge to make sure that declarations will be | 658 | * this is a kluge to make sure that declarations will be | |
658 | * aligned right if proc decl has an explicit type on it, i.e. | 659 | * aligned right if proc decl has an explicit type on it, i.e. | |
659 | * "int a(x) {..." | 660 | * "int a(x) {..." | |
660 | */ | 661 | */ | |
661 | parse(semicolon); /* I said this was a kluge... */ | 662 | parse(semicolon); /* I said this was a kluge... */ | |
662 | ps.in_or_st = false; /* turn off flag for structure decl or | 663 | ps.in_or_st = false; /* turn off flag for structure decl or | |
663 | * initialization */ | 664 | * initialization */ | |
664 | } | 665 | } | |
665 | /* parenthesized type following sizeof or offsetof is not a cast */ | 666 | /* parenthesized type following sizeof or offsetof is not a cast */ | |
666 | if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) | 667 | if (ps.keyword == rw_offsetof || ps.keyword == rw_sizeof) | |
667 | ps.not_cast_mask |= 1 << ps.p_l_follow; | 668 | ps.not_cast_mask |= 1 << ps.p_l_follow; | |
668 | } | 669 | } | |
669 | 670 | |||
670 | static void | 671 | static void | |
671 | process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl, | 672 | process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl, | |
672 | token_type hd_type) | 673 | token_type hd_type) | |
673 | { | 674 | { | |
674 | if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { | 675 | if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) { | |
675 | ps.last_u_d = true; | 676 | ps.last_u_d = true; | |
676 | ps.cast_mask &= (1 << ps.p_l_follow) - 1; | 677 | ps.cast_mask &= (1 << ps.p_l_follow) - 1; | |
677 | ps.want_blank = opt.space_after_cast; | 678 | ps.want_blank = opt.space_after_cast; | |
678 | } else | 679 | } else | |
679 | ps.want_blank = true; | 680 | ps.want_blank = true; | |
680 | ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; | 681 | ps.not_cast_mask &= (1 << ps.p_l_follow) - 1; | |
681 | 682 | |||
682 | if (--ps.p_l_follow < 0) { | 683 | if (--ps.p_l_follow < 0) { | |
683 | ps.p_l_follow = 0; | 684 | ps.p_l_follow = 0; | |
684 | diag(0, "Extra %c", *token); | 685 | diag(0, "Extra %c", *token); | |
685 | } | 686 | } | |
686 | 687 | |||
687 | if (e_code == s_code) /* if the paren starts the line */ | 688 | if (e_code == s_code) /* if the paren starts the line */ | |
688 | ps.paren_level = ps.p_l_follow; /* then indent it */ | 689 | ps.paren_level = ps.p_l_follow; /* then indent it */ | |
689 | 690 | |||
690 | *e_code++ = token[0]; | 691 | *e_code++ = token[0]; | |
691 | 692 | |||
692 | if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if | 693 | if (*inout_sp_sw && (ps.p_l_follow == 0)) { /* check for end of if | |
693 | * (...), or some such */ | 694 | * (...), or some such */ | |
694 | *inout_sp_sw = false; | 695 | *inout_sp_sw = false; | |
695 | *inout_force_nl = true; /* must force newline after if */ | 696 | *inout_force_nl = true; /* must force newline after if */ | |
696 | ps.last_u_d = true; /* inform lexi that a following | 697 | ps.last_u_d = true; /* inform lexi that a following | |
697 | * operator is unary */ | 698 | * operator is unary */ | |
698 | ps.in_stmt = false; /* dont use stmt continuation indentation */ | 699 | ps.in_stmt = false; /* dont use stmt continuation indentation */ | |
699 | 700 | |||
700 | parse(hd_type); /* let parser worry about if, or whatever */ | 701 | parse(hd_type); /* let parser worry about if, or whatever */ | |
701 | } | 702 | } | |
702 | ps.search_brace = opt.btype_2; /* this should ensure that constructs such | 703 | ps.search_brace = opt.btype_2; /* this should ensure that constructs such | |
703 | * as main(){...} and int[]{...} have their | 704 | * as main(){...} and int[]{...} have their | |
704 | * braces put in the right place */ | 705 | * braces put in the right place */ | |
705 | } | 706 | } | |
706 | 707 | |||
707 | static void | 708 | static void | |
708 | process_unary_op(int dec_ind, int tabs_to_var) | 709 | process_unary_op(int dec_ind, int tabs_to_var) | |
709 | { | 710 | { | |
710 | if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && | 711 | if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init && | |
711 | ps.procname[0] == '\0' && ps.paren_level == 0) { | 712 | ps.procname[0] == '\0' && ps.paren_level == 0) { | |
712 | /* pointer declarations */ | 713 | /* pointer declarations */ | |
713 | 714 | |||
714 | /* | 715 | /* | |
715 | * if this is a unary op in a declaration, we should indent | 716 | * if this is a unary op in a declaration, we should indent | |
716 | * this token | 717 | * this token | |
717 | */ | 718 | */ | |
718 | int i; | 719 | int i; | |
719 | for (i = 0; token[i]; ++i) | 720 | for (i = 0; token[i]; ++i) | |
720 | /* find length of token */; | 721 | /* find length of token */; | |
721 | indent_declaration(dec_ind - i, tabs_to_var); | 722 | indent_declaration(dec_ind - i, tabs_to_var); | |
722 | ps.dumped_decl_indent = true; | 723 | ps.dumped_decl_indent = true; | |
723 | } else if (ps.want_blank) | 724 | } else if (ps.want_blank) | |
724 | *e_code++ = ' '; | 725 | *e_code++ = ' '; | |
725 | 726 | |||
726 | { | 727 | { | |
727 | int len = e_token - s_token; | 728 | size_t len = e_token - s_token; | |
728 | 729 | |||
729 | check_size_code(len); | 730 | check_size_code(len); | |
730 | memcpy(e_code, token, len); | 731 | memcpy(e_code, token, len); | |
731 | e_code += len; | 732 | e_code += len; | |
732 | } | 733 | } | |
733 | ps.want_blank = false; | 734 | ps.want_blank = false; | |
734 | } | 735 | } | |
735 | 736 | |||
736 | static void | 737 | static void | |
737 | process_binary_op(void) | 738 | process_binary_op(void) | |
738 | { | 739 | { | |
739 | int len = e_token - s_token; | 740 | size_t len = e_token - s_token; | |
740 | 741 | |||
741 | check_size_code(len + 1); | 742 | check_size_code(len + 1); | |
742 | if (ps.want_blank) | 743 | if (ps.want_blank) | |
743 | *e_code++ = ' '; | 744 | *e_code++ = ' '; | |
744 | memcpy(e_code, token, len); | 745 | memcpy(e_code, token, len); | |
745 | e_code += len; | 746 | e_code += len; | |
746 | 747 | |||
747 | ps.want_blank = true; | 748 | ps.want_blank = true; | |
748 | } | 749 | } | |
749 | 750 | |||
750 | static void | 751 | static void | |
751 | process_postfix_op(void) | 752 | process_postfix_op(void) | |
752 | { | 753 | { | |
753 | *e_code++ = token[0]; | 754 | *e_code++ = token[0]; | |
754 | *e_code++ = token[1]; | 755 | *e_code++ = token[1]; | |
755 | ps.want_blank = true; | 756 | ps.want_blank = true; | |
756 | } | 757 | } | |
757 | 758 | |||
758 | static void | 759 | static void | |
759 | process_question(int *inout_squest) | 760 | process_question(int *inout_squest) | |
760 | { | 761 | { | |
761 | (*inout_squest)++; /* this will be used when a later colon | 762 | (*inout_squest)++; /* this will be used when a later colon | |
762 | * appears so we can distinguish the | 763 | * appears so we can distinguish the | |
763 | * <c>?<n>:<n> construct */ | 764 | * <c>?<n>:<n> construct */ | |
764 | if (ps.want_blank) | 765 | if (ps.want_blank) | |
765 | *e_code++ = ' '; | 766 | *e_code++ = ' '; | |
766 | *e_code++ = '?'; | 767 | *e_code++ = '?'; | |
767 | ps.want_blank = true; | 768 | ps.want_blank = true; | |
768 | } | 769 | } | |
769 | 770 | |||
770 | static void | 771 | static void | |
771 | process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase) | 772 | process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase) | |
772 | { | 773 | { | |
773 | if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */ | 774 | if (*inout_squest > 0) { /* it is part of the <c>?<n>: <n> construct */ | |
774 | --*inout_squest; | 775 | --*inout_squest; | |
775 | if (ps.want_blank) | 776 | if (ps.want_blank) | |
776 | *e_code++ = ' '; | 777 | *e_code++ = ' '; | |
777 | *e_code++ = ':'; | 778 | *e_code++ = ':'; | |
778 | ps.want_blank = true; | 779 | ps.want_blank = true; | |
779 | return; | 780 | return; | |
780 | } | 781 | } | |
781 | if (ps.in_or_st) { | 782 | if (ps.in_or_st) { | |
782 | *e_code++ = ':'; | 783 | *e_code++ = ':'; | |
783 | ps.want_blank = false; | 784 | ps.want_blank = false; | |
784 | return; | 785 | return; | |
785 | } | 786 | } | |
786 | ps.in_stmt = false; /* seeing a label does not imply we are in a | 787 | ps.in_stmt = false; /* seeing a label does not imply we are in a | |
787 | * stmt */ | 788 | * stmt */ | |
788 | /* | 789 | /* | |
789 | * turn everything so far into a label | 790 | * turn everything so far into a label | |
790 | */ | 791 | */ | |
791 | { | 792 | { | |
792 | int len = e_code - s_code; | 793 | size_t len = e_code - s_code; | |
793 | 794 | |||
794 | check_size_label(len + 3); | 795 | check_size_label(len + 3); | |
795 | memcpy(e_lab, s_code, len); | 796 | memcpy(e_lab, s_code, len); | |
796 | e_lab += len; | 797 | e_lab += len; | |
797 | *e_lab++ = ':'; | 798 | *e_lab++ = ':'; | |
798 | *e_lab = '\0'; | 799 | *e_lab = '\0'; | |
799 | e_code = s_code; | 800 | e_code = s_code; | |
800 | } | 801 | } | |
801 | *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by | 802 | *inout_force_nl = ps.pcase = *inout_scase; /* ps.pcase will be used by | |
802 | * dump_line to decide how to | 803 | * dump_line to decide how to | |
803 | * indent the label. force_nl | 804 | * indent the label. force_nl | |
804 | * will force a case n: to be | 805 | * will force a case n: to be | |
805 | * on a line by itself */ | 806 | * on a line by itself */ | |
806 | *inout_scase = false; | 807 | *inout_scase = false; | |
807 | ps.want_blank = false; | 808 | ps.want_blank = false; | |
808 | } | 809 | } | |
809 | 810 | |||
810 | static void | 811 | static void | |
811 | process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind, | 812 | process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind, | |
812 | int const tabs_to_var, int *inout_sp_sw, | 813 | int const tabs_to_var, int *inout_sp_sw, | |
813 | token_type const hd_type, | 814 | token_type const hd_type, | |
814 | int *inout_force_nl) | 815 | int *inout_force_nl) | |
815 | { | 816 | { | |
816 | if (ps.dec_nest == 0) | 817 | if (ps.dec_nest == 0) | |
817 | ps.in_or_st = false; /* we are not in an initialization or | 818 | ps.in_or_st = false; /* we are not in an initialization or | |
818 | * structure declaration */ | 819 | * structure declaration */ | |
819 | *inout_scase = false; /* these will only need resetting in an error */ | 820 | *inout_scase = false; /* these will only need resetting in an error */ | |
820 | *inout_squest = 0; | 821 | *inout_squest = 0; | |
821 | if (ps.last_token == rparen) | 822 | if (ps.last_token == rparen) | |
822 | ps.in_parameter_declaration = 0; | 823 | ps.in_parameter_declaration = 0; | |
823 | ps.cast_mask = 0; | 824 | ps.cast_mask = 0; | |
824 | ps.not_cast_mask = 0; | 825 | ps.not_cast_mask = 0; | |
825 | ps.block_init = 0; | 826 | ps.block_init = 0; | |
826 | ps.block_init_level = 0; | 827 | ps.block_init_level = 0; | |
827 | ps.just_saw_decl--; | 828 | ps.just_saw_decl--; | |
828 | 829 | |||
829 | if (ps.in_decl && s_code == e_code && !ps.block_init && | 830 | if (ps.in_decl && s_code == e_code && !ps.block_init && | |
830 | !ps.dumped_decl_indent && ps.paren_level == 0) { | 831 | !ps.dumped_decl_indent && ps.paren_level == 0) { | |
831 | /* indent stray semicolons in declarations */ | 832 | /* indent stray semicolons in declarations */ | |
832 | indent_declaration(dec_ind - 1, tabs_to_var); | 833 | indent_declaration(dec_ind - 1, tabs_to_var); | |
833 | ps.dumped_decl_indent = true; | 834 | ps.dumped_decl_indent = true; | |
834 | } | 835 | } | |
835 | 836 | |||
836 | ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level | 837 | ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level | |
837 | * structure declaration, we | 838 | * structure declaration, we | |
838 | * arent any more */ | 839 | * arent any more */ | |
839 | 840 | |||
840 | if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { | 841 | if ((!*inout_sp_sw || hd_type != for_exprs) && ps.p_l_follow > 0) { | |
841 | 842 | |||
842 | /* | 843 | /* | |
843 | * This should be true iff there were unbalanced parens in the | 844 | * This should be true iff there were unbalanced parens in the | |
844 | * stmt. It is a bit complicated, because the semicolon might | 845 | * stmt. It is a bit complicated, because the semicolon might | |
845 | * be in a for stmt | 846 | * be in a for stmt | |
846 | */ | 847 | */ | |
847 | diag(1, "Unbalanced parens"); | 848 | diag(1, "Unbalanced parens"); | |
848 | ps.p_l_follow = 0; | 849 | ps.p_l_follow = 0; | |
849 | if (*inout_sp_sw) { /* this is a check for an if, while, etc. with | 850 | if (*inout_sp_sw) { /* this is a check for an if, while, etc. with | |
850 | * unbalanced parens */ | 851 | * unbalanced parens */ | |
851 | *inout_sp_sw = false; | 852 | *inout_sp_sw = false; | |
852 | parse(hd_type); /* dont lose the if, or whatever */ | 853 | parse(hd_type); /* dont lose the if, or whatever */ | |
853 | } | 854 | } | |
854 | } | 855 | } | |
855 | *e_code++ = ';'; | 856 | *e_code++ = ';'; | |
856 | ps.want_blank = true; | 857 | ps.want_blank = true; | |
857 | ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the | 858 | ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the | |
858 | * middle of a stmt */ | 859 | * middle of a stmt */ | |
859 | 860 | |||
860 | if (!*inout_sp_sw) { /* if not if for (;;) */ | 861 | if (!*inout_sp_sw) { /* if not if for (;;) */ | |
861 | parse(semicolon); /* let parser know about end of stmt */ | 862 | parse(semicolon); /* let parser know about end of stmt */ | |
862 | *inout_force_nl = true;/* force newline after an end of stmt */ | 863 | *inout_force_nl = true;/* force newline after an end of stmt */ | |
863 | } | 864 | } | |
864 | } | 865 | } | |
865 | 866 | |||
866 | static void | 867 | static void | |
867 | process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type, | 868 | process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type, | |
868 | int *di_stack, int di_stack_cap, int *inout_dec_ind) | 869 | int *di_stack, int di_stack_cap, int *inout_dec_ind) | |
869 | { | 870 | { | |
870 | ps.in_stmt = false; /* dont indent the {} */ | 871 | ps.in_stmt = false; /* dont indent the {} */ | |
871 | if (!ps.block_init) | 872 | if (!ps.block_init) | |
872 | *inout_force_nl = true; /* force other stuff on same line as '{' onto | 873 | *inout_force_nl = true; /* force other stuff on same line as '{' onto | |
873 | * new line */ | 874 | * new line */ | |
874 | else if (ps.block_init_level <= 0) | 875 | else if (ps.block_init_level <= 0) | |
875 | ps.block_init_level = 1; | 876 | ps.block_init_level = 1; | |
876 | else | 877 | else | |
877 | ps.block_init_level++; | 878 | ps.block_init_level++; | |
878 | 879 | |||
879 | if (s_code != e_code && !ps.block_init) { | 880 | if (s_code != e_code && !ps.block_init) { | |
880 | if (!opt.btype_2) { | 881 | if (!opt.btype_2) { | |
881 | dump_line(); | 882 | dump_line(); | |
882 | ps.want_blank = false; | 883 | ps.want_blank = false; | |
883 | } else if (ps.in_parameter_declaration && !ps.in_or_st) { | 884 | } else if (ps.in_parameter_declaration && !ps.in_or_st) { | |
884 | ps.i_l_follow = 0; | 885 | ps.i_l_follow = 0; | |
885 | if (opt.function_brace_split) { /* dump the line prior | 886 | if (opt.function_brace_split) { /* dump the line prior | |
886 | * to the brace ... */ | 887 | * to the brace ... */ | |
887 | dump_line(); | 888 | dump_line(); | |
888 | ps.want_blank = false; | 889 | ps.want_blank = false; | |
889 | } else /* add a space between the decl and brace */ | 890 | } else /* add a space between the decl and brace */ | |
890 | ps.want_blank = true; | 891 | ps.want_blank = true; | |
891 | } | 892 | } | |
892 | } | 893 | } | |
893 | if (ps.in_parameter_declaration) | 894 | if (ps.in_parameter_declaration) | |
894 | prefix_blankline_requested = 0; | 895 | prefix_blankline_requested = 0; | |
895 | 896 | |||
896 | if (ps.p_l_follow > 0) { /* check for preceding unbalanced | 897 | if (ps.p_l_follow > 0) { /* check for preceding unbalanced | |
897 | * parens */ | 898 | * parens */ | |
898 | diag(1, "Unbalanced parens"); | 899 | diag(1, "Unbalanced parens"); | |
899 | ps.p_l_follow = 0; | 900 | ps.p_l_follow = 0; | |
900 | if (*inout_sp_sw) { /* check for unclosed if, for, etc. */ | 901 | if (*inout_sp_sw) { /* check for unclosed if, for, etc. */ | |
901 | *inout_sp_sw = false; | 902 | *inout_sp_sw = false; | |
902 | parse(hd_type); | 903 | parse(hd_type); | |
903 | ps.ind_level = ps.i_l_follow; | 904 | ps.ind_level = ps.i_l_follow; | |
904 | } | 905 | } | |
905 | } | 906 | } | |
906 | if (s_code == e_code) | 907 | if (s_code == e_code) | |
907 | ps.ind_stmt = false; /* dont put extra indentation on line | 908 | ps.ind_stmt = false; /* dont put extra indentation on line | |
908 | * with '{' */ | 909 | * with '{' */ | |
909 | if (ps.in_decl && ps.in_or_st) { /* this is either a structure | 910 | if (ps.in_decl && ps.in_or_st) { /* this is either a structure | |
910 | * declaration or an init */ | 911 | * declaration or an init */ | |
911 | di_stack[ps.dec_nest] = *inout_dec_ind; | 912 | di_stack[ps.dec_nest] = *inout_dec_ind; | |
912 | if (++ps.dec_nest == di_stack_cap) { | 913 | if (++ps.dec_nest == di_stack_cap) { | |
913 | diag(0, "Reached internal limit of %d struct levels", | 914 | diag(0, "Reached internal limit of %d struct levels", | |
914 | di_stack_cap); | 915 | di_stack_cap); | |
915 | ps.dec_nest--; | 916 | ps.dec_nest--; | |
916 | } | 917 | } | |
917 | /* ? dec_ind = 0; */ | 918 | /* ? dec_ind = 0; */ | |
918 | } else { | 919 | } else { | |
919 | ps.decl_on_line = false; /* we can't be in the middle of | 920 | ps.decl_on_line = false; /* we can't be in the middle of | |
920 | * a declaration, so don't do | 921 | * a declaration, so don't do | |
921 | * special indentation of | 922 | * special indentation of | |
922 | * comments */ | 923 | * comments */ | |
923 | if (opt.blanklines_after_declarations_at_proctop | 924 | if (opt.blanklines_after_declarations_at_proctop | |
924 | && ps.in_parameter_declaration) | 925 | && ps.in_parameter_declaration) | |
925 | postfix_blankline_requested = 1; | 926 | postfix_blankline_requested = 1; | |
926 | ps.in_parameter_declaration = 0; | 927 | ps.in_parameter_declaration = 0; | |
927 | ps.in_decl = false; | 928 | ps.in_decl = false; | |
928 | } | 929 | } | |
929 | *inout_dec_ind = 0; | 930 | *inout_dec_ind = 0; | |
930 | parse(lbrace); /* let parser know about this */ | 931 | parse(lbrace); /* let parser know about this */ | |
931 | if (ps.want_blank) /* put a blank before '{' if '{' is not at | 932 | if (ps.want_blank) /* put a blank before '{' if '{' is not at | |
932 | * start of line */ | 933 | * start of line */ | |
933 | *e_code++ = ' '; | 934 | *e_code++ = ' '; | |
934 | ps.want_blank = false; | 935 | ps.want_blank = false; | |
935 | *e_code++ = '{'; | 936 | *e_code++ = '{'; | |
936 | ps.just_saw_decl = 0; | 937 | ps.just_saw_decl = 0; | |
937 | } | 938 | } | |
938 | 939 | |||
939 | static void | 940 | static void | |
940 | process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack) | 941 | process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack) | |
941 | { | 942 | { | |
942 | if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be | 943 | if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be | |
943 | * omitted in declarations */ | 944 | * omitted in declarations */ | |
944 | parse(semicolon); | 945 | parse(semicolon); | |
945 | if (ps.p_l_follow) { /* check for unclosed if, for, else. */ | 946 | if (ps.p_l_follow) { /* check for unclosed if, for, else. */ | |
946 | diag(1, "Unbalanced parens"); | 947 | diag(1, "Unbalanced parens"); | |
947 | ps.p_l_follow = 0; | 948 | ps.p_l_follow = 0; | |
948 | *inout_sp_sw = false; | 949 | *inout_sp_sw = false; | |
949 | } | 950 | } | |
950 | ps.just_saw_decl = 0; | 951 | ps.just_saw_decl = 0; | |
951 | ps.block_init_level--; | 952 | ps.block_init_level--; | |
952 | if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */ | 953 | if (s_code != e_code && !ps.block_init) { /* '}' must be first on line */ | |
953 | if (opt.verbose) | 954 | if (opt.verbose) | |
954 | diag(0, "Line broken"); | 955 | diag(0, "Line broken"); | |
955 | dump_line(); | 956 | dump_line(); | |
956 | } | 957 | } | |
957 | *e_code++ = '}'; | 958 | *e_code++ = '}'; | |
958 | ps.want_blank = true; | 959 | ps.want_blank = true; | |
959 | ps.in_stmt = ps.ind_stmt = false; | 960 | ps.in_stmt = ps.ind_stmt = false; | |
960 | if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */ | 961 | if (ps.dec_nest > 0) { /* we are in multi-level structure declaration */ | |
961 | *inout_dec_ind = di_stack[--ps.dec_nest]; | 962 | *inout_dec_ind = di_stack[--ps.dec_nest]; | |
962 | if (ps.dec_nest == 0 && !ps.in_parameter_declaration) | 963 | if (ps.dec_nest == 0 && !ps.in_parameter_declaration) | |
963 | ps.just_saw_decl = 2; | 964 | ps.just_saw_decl = 2; | |
964 | ps.in_decl = true; | 965 | ps.in_decl = true; | |
965 | } | 966 | } | |
966 | prefix_blankline_requested = 0; | 967 | prefix_blankline_requested = 0; | |
967 | parse(rbrace); /* let parser know about this */ | 968 | parse(rbrace); /* let parser know about this */ | |
968 | ps.search_brace = opt.cuddle_else | 969 | ps.search_brace = opt.cuddle_else | |
969 | && ps.p_stack[ps.tos] == if_expr_stmt | 970 | && ps.p_stack[ps.tos] == if_expr_stmt | |
970 | && ps.il[ps.tos] >= ps.ind_level; | 971 | && ps.il[ps.tos] >= ps.ind_level; | |
971 | if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) | 972 | if (ps.tos <= 1 && opt.blanklines_after_procs && ps.dec_nest <= 0) | |
972 | postfix_blankline_requested = 1; | 973 | postfix_blankline_requested = 1; | |
973 | } | 974 | } | |
974 | 975 | |||
975 | static void | 976 | static void | |
976 | process_keyword_do_else(int *inout_force_nl, int *inout_last_else) | 977 | process_keyword_do_else(int *inout_force_nl, int *inout_last_else) | |
977 | { | 978 | { | |
978 | ps.in_stmt = false; | 979 | ps.in_stmt = false; | |
979 | if (*token == 'e') { | 980 | if (*token == 'e') { | |
980 | if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { | 981 | if (e_code != s_code && (!opt.cuddle_else || e_code[-1] != '}')) { | |
981 | if (opt.verbose) | 982 | if (opt.verbose) | |
982 | diag(0, "Line broken"); | 983 | diag(0, "Line broken"); | |
983 | dump_line(); /* make sure this starts a line */ | 984 | dump_line(); /* make sure this starts a line */ | |
984 | ps.want_blank = false; | 985 | ps.want_blank = false; | |
985 | } | 986 | } | |
986 | *inout_force_nl = true;/* also, following stuff must go onto new line */ | 987 | *inout_force_nl = true;/* also, following stuff must go onto new line */ | |
987 | *inout_last_else = 1; | 988 | *inout_last_else = 1; | |
988 | parse(keyword_else); | 989 | parse(keyword_else); | |
989 | } else { | 990 | } else { | |
990 | if (e_code != s_code) { /* make sure this starts a line */ | 991 | if (e_code != s_code) { /* make sure this starts a line */ | |
991 | if (opt.verbose) | 992 | if (opt.verbose) | |
992 | diag(0, "Line broken"); | 993 | diag(0, "Line broken"); | |
993 | dump_line(); | 994 | dump_line(); | |
994 | ps.want_blank = false; | 995 | ps.want_blank = false; | |
995 | } | 996 | } | |
996 | *inout_force_nl = true;/* also, following stuff must go onto new line */ | 997 | *inout_force_nl = true;/* also, following stuff must go onto new line */ | |
997 | *inout_last_else = 0; | 998 | *inout_last_else = 0; | |
998 | parse(keyword_do); | 999 | parse(keyword_do); | |
999 | } | 1000 | } | |
1000 | } | 1001 | } | |
1001 | 1002 | |||
1002 | static void | 1003 | static void | |
1003 | process_decl(int *out_dec_ind, int *out_tabs_to_var) | 1004 | process_decl(int *out_dec_ind, int *out_tabs_to_var) | |
1004 | { | 1005 | { | |
1005 | parse(decl); /* let parser worry about indentation */ | 1006 | parse(decl); /* let parser worry about indentation */ | |
1006 | if (ps.last_token == rparen && ps.tos <= 1) { | 1007 | if (ps.last_token == rparen && ps.tos <= 1) { | |
1007 | if (s_code != e_code) { | 1008 | if (s_code != e_code) { | |
1008 | dump_line(); | 1009 | dump_line(); | |
1009 | ps.want_blank = 0; | 1010 | ps.want_blank = 0; | |
1010 | } | 1011 | } | |
1011 | } | 1012 | } | |
1012 | if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { | 1013 | if (ps.in_parameter_declaration && opt.indent_parameters && ps.dec_nest == 0) { | |
1013 | ps.ind_level = ps.i_l_follow = 1; | 1014 | ps.ind_level = ps.i_l_follow = 1; | |
1014 | ps.ind_stmt = 0; | 1015 | ps.ind_stmt = 0; | |
1015 | } | 1016 | } | |
1016 | ps.in_or_st = true; /* this might be a structure or initialization | 1017 | ps.in_or_st = true; /* this might be a structure or initialization | |
1017 | * declaration */ | 1018 | * declaration */ | |
1018 | ps.in_decl = ps.decl_on_line = ps.last_token != type_def; | 1019 | ps.in_decl = ps.decl_on_line = ps.last_token != type_def; | |
1019 | if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) | 1020 | if ( /* !ps.in_or_st && */ ps.dec_nest <= 0) | |
1020 | ps.just_saw_decl = 2; | 1021 | ps.just_saw_decl = 2; | |
1021 | prefix_blankline_requested = 0; | 1022 | prefix_blankline_requested = 0; | |
1022 | int i; | 1023 | int i; | |
1023 | for (i = 0; token[i++];); /* get length of token */ | 1024 | for (i = 0; token[i++];); /* get length of token */ | |
1024 | 1025 | |||
1025 | if (ps.ind_level == 0 || ps.dec_nest > 0) { | 1026 | if (ps.ind_level == 0 || ps.dec_nest > 0) { | |
1026 | /* global variable or struct member in local variable */ | 1027 | /* global variable or struct member in local variable */ | |
1027 | *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; | 1028 | *out_dec_ind = opt.decl_indent > 0 ? opt.decl_indent : i; | |
1028 | *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); | 1029 | *out_tabs_to_var = (opt.use_tabs ? opt.decl_indent > 0 : 0); | |
1029 | } else { | 1030 | } else { | |
1030 | /* local variable */ | 1031 | /* local variable */ | |
1031 | *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; | 1032 | *out_dec_ind = opt.local_decl_indent > 0 ? opt.local_decl_indent : i; | |
1032 | *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); | 1033 | *out_tabs_to_var = (opt.use_tabs ? opt.local_decl_indent > 0 : 0); | |
1033 | } | 1034 | } | |
1034 | } | 1035 | } | |
1035 | 1036 | |||
1036 | static void | 1037 | static void | |
1037 | process_ident(token_type type_code, int dec_ind, int tabs_to_var, | 1038 | process_ident(token_type type_code, int dec_ind, int tabs_to_var, | |
1038 | int *inout_sp_sw, int *inout_force_nl, token_type hd_type) | 1039 | int *inout_sp_sw, int *inout_force_nl, token_type hd_type) | |
1039 | { | 1040 | { | |
1040 | if (ps.in_decl) { | 1041 | if (ps.in_decl) { | |
1041 | if (type_code == funcname) { | 1042 | if (type_code == funcname) { | |
1042 | ps.in_decl = false; | 1043 | ps.in_decl = false; | |
1043 | if (opt.procnames_start_line && s_code != e_code) { | 1044 | if (opt.procnames_start_line && s_code != e_code) { | |
1044 | *e_code = '\0'; | 1045 | *e_code = '\0'; | |
1045 | dump_line(); | 1046 | dump_line(); | |
1046 | } else if (ps.want_blank) { | 1047 | } else if (ps.want_blank) { | |
1047 | *e_code++ = ' '; | 1048 | *e_code++ = ' '; | |
1048 | } | 1049 | } | |
1049 | ps.want_blank = false; | 1050 | ps.want_blank = false; | |
1050 | } else if (!ps.block_init && !ps.dumped_decl_indent && | 1051 | } else if (!ps.block_init && !ps.dumped_decl_indent && | |
1051 | ps.paren_level == 0) { /* if we are in a declaration, we | 1052 | ps.paren_level == 0) { /* if we are in a declaration, we | |
1052 | * must indent identifier */ | 1053 | * must indent identifier */ | |
1053 | indent_declaration(dec_ind, tabs_to_var); | 1054 | indent_declaration(dec_ind, tabs_to_var); | |
1054 | ps.dumped_decl_indent = true; | 1055 | ps.dumped_decl_indent = true; | |
1055 | ps.want_blank = false; | 1056 | ps.want_blank = false; | |
1056 | } | 1057 | } | |
1057 | } else if (*inout_sp_sw && ps.p_l_follow == 0) { | 1058 | } else if (*inout_sp_sw && ps.p_l_follow == 0) { | |
1058 | *inout_sp_sw = false; | 1059 | *inout_sp_sw = false; | |
1059 | *inout_force_nl = true; | 1060 | *inout_force_nl = true; | |
1060 | ps.last_u_d = true; | 1061 | ps.last_u_d = true; | |
1061 | ps.in_stmt = false; | 1062 | ps.in_stmt = false; | |
1062 | parse(hd_type); | 1063 | parse(hd_type); | |
1063 | } | 1064 | } | |
1064 | } | 1065 | } | |
1065 | 1066 | |||
1066 | static void | 1067 | static void | |
1067 | copy_id(void) | 1068 | copy_id(void) | |
1068 | { | 1069 | { | |
1069 | int len = e_token - s_token; | 1070 | size_t len = e_token - s_token; | |
1070 | 1071 | |||
1071 | check_size_code(len + 1); | 1072 | check_size_code(len + 1); | |
1072 | if (ps.want_blank) | 1073 | if (ps.want_blank) | |
1073 | *e_code++ = ' '; | 1074 | *e_code++ = ' '; | |
1074 | memcpy(e_code, s_token, len); | 1075 | memcpy(e_code, s_token, len); | |
1075 | e_code += len; | 1076 | e_code += len; | |
1076 | } | 1077 | } | |
1077 | 1078 | |||
1078 | static void | 1079 | static void | |
1079 | process_string_prefix(void) | 1080 | process_string_prefix(void) | |
1080 | { | 1081 | { | |
1081 | int len = e_token - s_token; | 1082 | size_t len = e_token - s_token; | |
1082 | 1083 | |||
1083 | check_size_code(len + 1); | 1084 | check_size_code(len + 1); | |
1084 | if (ps.want_blank) | 1085 | if (ps.want_blank) | |
1085 | *e_code++ = ' '; | 1086 | *e_code++ = ' '; | |
1086 | memcpy(e_code, token, len); | 1087 | memcpy(e_code, token, len); | |
1087 | e_code += len; | 1088 | e_code += len; | |
1088 | 1089 | |||
1089 | ps.want_blank = false; | 1090 | ps.want_blank = false; | |
1090 | } | 1091 | } | |
1091 | 1092 | |||
1092 | static void | 1093 | static void | |
1093 | process_period(void) | 1094 | process_period(void) | |
1094 | { | 1095 | { | |
1095 | *e_code++ = '.'; /* move the period into line */ | 1096 | *e_code++ = '.'; /* move the period into line */ | |
1096 | ps.want_blank = false; /* dont put a blank after a period */ | 1097 | ps.want_blank = false; /* dont put a blank after a period */ | |
1097 | } | 1098 | } | |
1098 | 1099 | |||
1099 | static void | 1100 | static void | |
1100 | process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl) | 1101 | process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl) | |
1101 | { | 1102 | { | |
1102 | ps.want_blank = (s_code != e_code); /* only put blank after comma | 1103 | ps.want_blank = (s_code != e_code); /* only put blank after comma | |
1103 | * if comma does not start the line */ | 1104 | * if comma does not start the line */ | |
1104 | if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && | 1105 | if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init && | |
1105 | !ps.dumped_decl_indent && ps.paren_level == 0) { | 1106 | !ps.dumped_decl_indent && ps.paren_level == 0) { | |
1106 | /* indent leading commas and not the actual identifiers */ | 1107 | /* indent leading commas and not the actual identifiers */ | |
1107 | indent_declaration(dec_ind - 1, tabs_to_var); | 1108 | indent_declaration(dec_ind - 1, tabs_to_var); | |
1108 | ps.dumped_decl_indent = true; | 1109 | ps.dumped_decl_indent = true; | |
1109 | } | 1110 | } | |
1110 | *e_code++ = ','; | 1111 | *e_code++ = ','; | |
1111 | if (ps.p_l_follow == 0) { | 1112 | if (ps.p_l_follow == 0) { | |
1112 | if (ps.block_init_level <= 0) | 1113 | if (ps.block_init_level <= 0) | |
1113 | ps.block_init = 0; | 1114 | ps.block_init = 0; | |
1114 | if (break_comma && (!opt.leave_comma || | 1115 | if (break_comma && (!opt.leave_comma || | |
1115 | indentation_after_range( | 1116 | indentation_after_range( | |
1116 | compute_code_indent(), s_code, e_code) | 1117 | compute_code_indent(), s_code, e_code) | |
1117 | >= opt.max_line_length - opt.tabsize)) | 1118 | >= opt.max_line_length - opt.tabsize)) | |
1118 | *inout_force_nl = true; | 1119 | *inout_force_nl = true; | |
1119 | } | 1120 | } | |
1120 | } | 1121 | } | |
1121 | 1122 | |||
1122 | static void | 1123 | static void | |
1123 | process_preprocessing(void) | 1124 | process_preprocessing(void) | |
1124 | { | 1125 | { | |
1125 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | 1126 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | |
1126 | dump_line(); | 1127 | dump_line(); | |
1127 | check_size_label(1); | 1128 | check_size_label(1); | |
1128 | *e_lab++ = '#'; /* move whole line to 'label' buffer */ | 1129 | *e_lab++ = '#'; /* move whole line to 'label' buffer */ | |
1129 | 1130 | |||
1130 | { | 1131 | { | |
1131 | int in_comment = 0; | 1132 | int in_comment = 0; | |
1132 | int com_start = 0; | 1133 | int com_start = 0; | |
1133 | char quote = '\0'; | 1134 | char quote = '\0'; | |
1134 | int com_end = 0; | 1135 | int com_end = 0; | |
1135 | 1136 | |||
1136 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | 1137 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { | |
1137 | buf_ptr++; | 1138 | buf_ptr++; | |
1138 | if (buf_ptr >= buf_end) | 1139 | if (buf_ptr >= buf_end) | |
1139 | fill_buffer(); | 1140 | fill_buffer(); | |
1140 | } | 1141 | } | |
1141 | while (*buf_ptr != '\n' || (in_comment && !had_eof)) { | 1142 | while (*buf_ptr != '\n' || (in_comment && !had_eof)) { | |
1142 | check_size_label(2); | 1143 | check_size_label(2); | |
1143 | *e_lab = *buf_ptr++; | 1144 | *e_lab = *buf_ptr++; | |
1144 | if (buf_ptr >= buf_end) | 1145 | if (buf_ptr >= buf_end) | |
1145 | fill_buffer(); | 1146 | fill_buffer(); | |
1146 | switch (*e_lab++) { | 1147 | switch (*e_lab++) { | |
1147 | case '\\': | 1148 | case '\\': | |
1148 | if (!in_comment) { | 1149 | if (!in_comment) { | |
1149 | *e_lab++ = *buf_ptr++; | 1150 | *e_lab++ = *buf_ptr++; | |
1150 | if (buf_ptr >= buf_end) | 1151 | if (buf_ptr >= buf_end) | |
1151 | fill_buffer(); | 1152 | fill_buffer(); | |
1152 | } | 1153 | } | |
1153 | break; | 1154 | break; | |
1154 | case '/': | 1155 | case '/': | |
1155 | if (*buf_ptr == '*' && !in_comment && quote == '\0') { | 1156 | if (*buf_ptr == '*' && !in_comment && quote == '\0') { | |
1156 | in_comment = 1; | 1157 | in_comment = 1; | |
1157 | *e_lab++ = *buf_ptr++; | 1158 | *e_lab++ = *buf_ptr++; | |
1158 | com_start = e_lab - s_lab - 2; | 1159 | com_start = (int)(e_lab - s_lab) - 2; | |
1159 | } | 1160 | } | |
1160 | break; | 1161 | break; | |
1161 | case '"': | 1162 | case '"': | |
1162 | if (quote == '"') | 1163 | if (quote == '"') | |
1163 | quote = '\0'; | 1164 | quote = '\0'; | |
1164 | else if (quote == '\0') | 1165 | else if (quote == '\0') | |
1165 | quote = '"'; | 1166 | quote = '"'; | |
1166 | break; | 1167 | break; | |
1167 | case '\'': | 1168 | case '\'': | |
1168 | if (quote == '\'') | 1169 | if (quote == '\'') | |
1169 | quote = '\0'; | 1170 | quote = '\0'; | |
1170 | else if (quote == '\0') | 1171 | else if (quote == '\0') | |
1171 | quote = '\''; | 1172 | quote = '\''; | |
1172 | break; | 1173 | break; | |
1173 | case '*': | 1174 | case '*': | |
1174 | if (*buf_ptr == '/' && in_comment) { | 1175 | if (*buf_ptr == '/' && in_comment) { | |
1175 | in_comment = 0; | 1176 | in_comment = 0; | |
1176 | *e_lab++ = *buf_ptr++; | 1177 | *e_lab++ = *buf_ptr++; | |
1177 | com_end = e_lab - s_lab; | 1178 | com_end = (int)(e_lab - s_lab); | |
1178 | } | 1179 | } | |
1179 | break; | 1180 | break; | |
1180 | } | 1181 | } | |
1181 | } | 1182 | } | |
1182 | 1183 | |||
1183 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | 1184 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | |
1184 | e_lab--; | 1185 | e_lab--; | |
1185 | if (e_lab - s_lab == com_end && bp_save == NULL) { | 1186 | if (e_lab - s_lab == com_end && bp_save == NULL) { | |
1186 | /* comment on preprocessor line */ | 1187 | /* comment on preprocessor line */ | |
1187 | if (sc_end == NULL) { /* if this is the first comment, | 1188 | if (sc_end == NULL) { /* if this is the first comment, | |
1188 | * we must set up the buffer */ | 1189 | * we must set up the buffer */ | |
1189 | save_com = sc_buf; | 1190 | save_com = sc_buf; | |
1190 | sc_end = &save_com[0]; | 1191 | sc_end = &save_com[0]; | |
1191 | } else { | 1192 | } else { | |
1192 | *sc_end++ = '\n'; /* add newline between | 1193 | *sc_end++ = '\n'; /* add newline between | |
1193 | * comments */ | 1194 | * comments */ | |
1194 | *sc_end++ = ' '; | 1195 | *sc_end++ = ' '; | |
1195 | --line_no; | 1196 | --line_no; | |
1196 | } | 1197 | } | |
1197 | if (sc_end - save_com + com_end - com_start > sc_size) | 1198 | if (sc_end - save_com + com_end - com_start > sc_size) | |
1198 | errx(1, "input too long"); | 1199 | errx(1, "input too long"); | |
1199 | memmove(sc_end, s_lab + com_start, com_end - com_start); | 1200 | memmove(sc_end, s_lab + com_start, com_end - com_start); | |
1200 | sc_end += com_end - com_start; | 1201 | sc_end += com_end - com_start; | |
1201 | e_lab = s_lab + com_start; | 1202 | e_lab = s_lab + com_start; | |
1202 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | 1203 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | |
1203 | e_lab--; | 1204 | e_lab--; | |
1204 | bp_save = buf_ptr; /* save current input buffer */ | 1205 | bp_save = buf_ptr; /* save current input buffer */ | |
1205 | be_save = buf_end; | 1206 | be_save = buf_end; | |
1206 | buf_ptr = save_com; /* fix so that subsequent calls to lexi will | 1207 | buf_ptr = save_com; /* fix so that subsequent calls to lexi will | |
1207 | * take tokens out of save_com */ | 1208 | * take tokens out of save_com */ | |
1208 | *sc_end++ = ' '; /* add trailing blank, just in case */ | 1209 | *sc_end++ = ' '; /* add trailing blank, just in case */ | |
1209 | buf_end = sc_end; | 1210 | buf_end = sc_end; | |
1210 | sc_end = NULL; | 1211 | sc_end = NULL; | |
1211 | debug_println("switched buf_ptr to save_com"); | 1212 | debug_println("switched buf_ptr to save_com"); | |
1212 | } | 1213 | } | |
1213 | check_size_label(1); | 1214 | check_size_label(1); | |
1214 | *e_lab = '\0'; /* null terminate line */ | 1215 | *e_lab = '\0'; /* null terminate line */ | |
1215 | ps.pcase = false; | 1216 | ps.pcase = false; | |
1216 | } | 1217 | } | |
1217 | 1218 | |||
1218 | if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ | 1219 | if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */ | |
1219 | if ((size_t)ifdef_level < nitems(state_stack)) { | 1220 | if ((size_t)ifdef_level < nitems(state_stack)) { | |
1220 | match_state[ifdef_level].tos = -1; | 1221 | match_state[ifdef_level].tos = -1; | |
1221 | state_stack[ifdef_level++] = ps; | 1222 | state_stack[ifdef_level++] = ps; | |
1222 | } else | 1223 | } else | |
1223 | diag(1, "#if stack overflow"); | 1224 | diag(1, "#if stack overflow"); | |
1224 | } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ | 1225 | } else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */ | |
1225 | if (ifdef_level <= 0) | 1226 | if (ifdef_level <= 0) | |
1226 | diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); | 1227 | diag(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else"); | |
1227 | else { | 1228 | else { | |
1228 | match_state[ifdef_level - 1] = ps; | 1229 | match_state[ifdef_level - 1] = ps; | |
1229 | ps = state_stack[ifdef_level - 1]; | 1230 | ps = state_stack[ifdef_level - 1]; | |
1230 | } | 1231 | } | |
1231 | } else if (strncmp(s_lab, "#endif", 6) == 0) { | 1232 | } else if (strncmp(s_lab, "#endif", 6) == 0) { | |
1232 | if (ifdef_level <= 0) | 1233 | if (ifdef_level <= 0) | |
1233 | diag(1, "Unmatched #endif"); | 1234 | diag(1, "Unmatched #endif"); | |
1234 | else | 1235 | else | |
1235 | ifdef_level--; | 1236 | ifdef_level--; | |
1236 | } else { | 1237 | } else { | |
1237 | static const struct directives { | 1238 | static const struct directives { | |
1238 | int size; | 1239 | int size; | |
1239 | const char *string; | 1240 | const char *string; | |
1240 | } recognized[] = { | 1241 | } recognized[] = { | |
1241 | {7, "include"}, | 1242 | {7, "include"}, | |
1242 | {6, "define"}, | 1243 | {6, "define"}, | |
1243 | {5, "undef"}, | 1244 | {5, "undef"}, | |
1244 | {4, "line"}, | 1245 | {4, "line"}, | |
1245 | {5, "error"}, | 1246 | {5, "error"}, | |
1246 | {6, "pragma"} | 1247 | {6, "pragma"} | |
1247 | }; | 1248 | }; | |
1248 | int d = nitems(recognized); | 1249 | int d = nitems(recognized); | |
1249 | while (--d >= 0) | 1250 | while (--d >= 0) | |
1250 | if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) | 1251 | if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0) | |
1251 | break; | 1252 | break; | |
1252 | if (d < 0) { | 1253 | if (d < 0) { | |
1253 | diag(1, "Unrecognized cpp directive"); | 1254 | diag(1, "Unrecognized cpp directive"); | |
1254 | return; | 1255 | return; | |
1255 | } | 1256 | } | |
1256 | } | 1257 | } | |
1257 | if (opt.blanklines_around_conditional_compilation) { | 1258 | if (opt.blanklines_around_conditional_compilation) { | |
1258 | postfix_blankline_requested++; | 1259 | postfix_blankline_requested++; | |
1259 | n_real_blanklines = 0; | 1260 | n_real_blanklines = 0; | |
1260 | } else { | 1261 | } else { | |
1261 | postfix_blankline_requested = 0; | 1262 | postfix_blankline_requested = 0; | |
1262 | prefix_blankline_requested = 0; | 1263 | prefix_blankline_requested = 0; | |
1263 | } | 1264 | } | |
1264 | 1265 | |||
1265 | /* | 1266 | /* | |
1266 | * subsequent processing of the newline character will cause the line to | 1267 | * subsequent processing of the newline character will cause the line to | |
1267 | * be printed | 1268 | * be printed | |
1268 | */ | 1269 | */ | |
1269 | } | 1270 | } | |
1270 | 1271 | |||
1271 | static void | 1272 | static void | |
1272 | main_loop(void) | 1273 | main_loop(void) | |
1273 | { | 1274 | { | |
1274 | token_type type_code; | 1275 | token_type type_code; | |
1275 | int force_nl; /* when true, code must be broken */ | 1276 | int force_nl; /* when true, code must be broken */ | |
1276 | int last_else = false; /* true iff last keyword was an else */ | 1277 | int last_else = false; /* true iff last keyword was an else */ | |
1277 | int dec_ind; /* current indentation for declarations */ | 1278 | int dec_ind; /* current indentation for declarations */ | |
1278 | int di_stack[20]; /* a stack of structure indentation levels */ | 1279 | int di_stack[20]; /* a stack of structure indentation levels */ | |
1279 | int tabs_to_var; /* true if using tabs to indent to var name */ | 1280 | int tabs_to_var; /* true if using tabs to indent to var name */ | |
1280 | int sp_sw; /* when true, we are in the expression of | 1281 | int sp_sw; /* when true, we are in the expression of | |
1281 | * if(...), while(...), etc. */ | 1282 | * if(...), while(...), etc. */ | |
1282 | token_type hd_type = end_of_file; /* used to store type of stmt | 1283 | token_type hd_type = end_of_file; /* used to store type of stmt | |
1283 | * for if (...), for (...), etc */ | 1284 | * for if (...), for (...), etc */ | |
1284 | int squest; /* when this is positive, we have seen a ? | 1285 | int squest; /* when this is positive, we have seen a ? | |
1285 | * without the matching : in a <c>?<s>:<s> | 1286 | * without the matching : in a <c>?<s>:<s> | |
1286 | * construct */ | 1287 | * construct */ | |
1287 | int scase; /* set to true when we see a case, so we will | 1288 | int scase; /* set to true when we see a case, so we will | |
1288 | * know what to do with the following colon */ | 1289 | * know what to do with the following colon */ | |
1289 | 1290 | |||
1290 | sp_sw = force_nl = false; | 1291 | sp_sw = force_nl = false; | |
1291 | dec_ind = 0; | 1292 | dec_ind = 0; | |
1292 | di_stack[ps.dec_nest = 0] = 0; | 1293 | di_stack[ps.dec_nest = 0] = 0; | |
1293 | scase = false; | 1294 | scase = false; | |
1294 | squest = 0; | 1295 | squest = 0; | |
1295 | tabs_to_var = 0; | 1296 | tabs_to_var = 0; | |
1296 | 1297 | |||
1297 | while (1) { /* this is the main loop. it will go until we | 1298 | for (;;) { /* this is the main loop. it will go until we | |
1298 | * reach eof */ | 1299 | * reach eof */ | |
1299 | int comment_buffered = false; | 1300 | int comment_buffered = false; | |
1300 | 1301 | |||
1301 | type_code = lexi(&ps); /* lexi reads one token. The actual | 1302 | type_code = lexi(&ps); /* lexi reads one token. The actual | |
1302 | * characters read are stored in "token". lexi | 1303 | * characters read are stored in "token". lexi | |
1303 | * returns a code indicating the type of token */ | 1304 | * returns a code indicating the type of token */ | |
1304 | 1305 | |||
1305 | /* | 1306 | /* | |
1306 | * The following code moves newlines and comments following an if (), | 1307 | * The following code moves newlines and comments following an if (), | |
1307 | * while (), else, etc. up to the start of the following stmt to | 1308 | * while (), else, etc. up to the start of the following stmt to | |
1308 | * a buffer. This allows proper handling of both kinds of brace | 1309 | * a buffer. This allows proper handling of both kinds of brace | |
1309 | * placement (-br, -bl) and cuddling "else" (-ce). | 1310 | * placement (-br, -bl) and cuddling "else" (-ce). | |
1310 | */ | 1311 | */ | |
1311 | search_brace(&type_code, &force_nl, &comment_buffered, &last_else); | 1312 | search_brace(&type_code, &force_nl, &comment_buffered, &last_else); | |
1312 | 1313 | |||
1313 | if (type_code == end_of_file) { | 1314 | if (type_code == end_of_file) { | |
1314 | process_end_of_file(); | 1315 | process_end_of_file(); | |
1315 | return; | 1316 | return; | |
1316 | } | 1317 | } | |
1317 | 1318 | |||
1318 | if ( | 1319 | if ( | |
1319 | type_code != comment && | 1320 | type_code != comment && | |
1320 | type_code != newline && | 1321 | type_code != newline && | |
1321 | type_code != preprocessing && | 1322 | type_code != preprocessing && | |
1322 | type_code != form_feed) { | 1323 | type_code != form_feed) { | |
1323 | process_comment_in_code(type_code, &force_nl); | 1324 | process_comment_in_code(type_code, &force_nl); | |
1324 | 1325 | |||
1325 | } else if (type_code != comment) /* preserve force_nl thru a comment */ | 1326 | } else if (type_code != comment) /* preserve force_nl thru a comment */ | |
1326 | force_nl = false; /* cancel forced newline after newline, form | 1327 | force_nl = false; /* cancel forced newline after newline, form | |
1327 | * feed, etc */ | 1328 | * feed, etc */ | |
1328 | 1329 | |||
1329 | 1330 | |||
1330 | 1331 | |||
1331 | /*-----------------------------------------------------*\ | 1332 | /*-----------------------------------------------------*\ | |
1332 | | do switch on type of token scanned | | 1333 | | do switch on type of token scanned | | |
1333 | \*-----------------------------------------------------*/ | 1334 | \*-----------------------------------------------------*/ | |
1334 | check_size_code(3); /* maximum number of increments of e_code | 1335 | check_size_code(3); /* maximum number of increments of e_code | |
1335 | * before the next check_size_code or | 1336 | * before the next check_size_code or | |
1336 | * dump_line() is 2. After that there's the | 1337 | * dump_line() is 2. After that there's the | |
1337 | * final increment for the null character. */ | 1338 | * final increment for the null character. */ | |
1338 | switch (type_code) { /* now, decide what to do with the token */ | 1339 | switch (type_code) { /* now, decide what to do with the token */ | |
1339 | 1340 | |||
1340 | case form_feed: /* found a form feed in line */ | 1341 | case form_feed: /* found a form feed in line */ | |
1341 | process_form_feed(); | 1342 | process_form_feed(); | |
1342 | break; | 1343 | break; | |
1343 | 1344 | |||
1344 | case newline: | 1345 | case newline: | |
1345 | process_newline(); | 1346 | process_newline(); | |
1346 | break; | 1347 | break; | |
1347 | 1348 | |||
1348 | case lparen: /* got a '(' or '[' */ | 1349 | case lparen: /* got a '(' or '[' */ | |
1349 | process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw); | 1350 | process_lparen_or_lbracket(dec_ind, tabs_to_var, sp_sw); | |
1350 | break; | 1351 | break; | |
1351 | 1352 | |||
1352 | case rparen: /* got a ')' or ']' */ | 1353 | case rparen: /* got a ')' or ']' */ | |
1353 | process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type); | 1354 | process_rparen_or_rbracket(&sp_sw, &force_nl, hd_type); | |
1354 | break; | 1355 | break; | |
1355 | 1356 | |||
1356 | case unary_op: /* this could be any unary operation */ | 1357 | case unary_op: /* this could be any unary operation */ | |
1357 | process_unary_op(dec_ind, tabs_to_var); | 1358 | process_unary_op(dec_ind, tabs_to_var); | |
1358 | break; | 1359 | break; | |
1359 | 1360 | |||
1360 | case binary_op: /* any binary operation */ | 1361 | case binary_op: /* any binary operation */ | |
1361 | process_binary_op(); | 1362 | process_binary_op(); | |
1362 | break; | 1363 | break; | |
1363 | 1364 | |||
1364 | case postfix_op: /* got a trailing ++ or -- */ | 1365 | case postfix_op: /* got a trailing ++ or -- */ | |
1365 | process_postfix_op(); | 1366 | process_postfix_op(); | |
1366 | break; | 1367 | break; | |
1367 | 1368 | |||
1368 | case question: /* got a ? */ | 1369 | case question: /* got a ? */ | |
1369 | process_question(&squest); | 1370 | process_question(&squest); | |
1370 | break; | 1371 | break; | |
1371 | 1372 | |||
1372 | case case_label: /* got word 'case' or 'default' */ | 1373 | case case_label: /* got word 'case' or 'default' */ | |
1373 | scase = true; /* so we can process the later colon properly */ | 1374 | scase = true; /* so we can process the later colon properly */ | |
1374 | goto copy_id; | 1375 | goto copy_id; | |
1375 | 1376 | |||
1376 | case colon: /* got a ':' */ | 1377 | case colon: /* got a ':' */ | |
1377 | process_colon(&squest, &force_nl, &scase); | 1378 | process_colon(&squest, &force_nl, &scase); | |
1378 | break; | 1379 | break; | |
1379 | 1380 | |||
1380 | case semicolon: /* got a ';' */ | 1381 | case semicolon: /* got a ';' */ | |
1381 | process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw, | 1382 | process_semicolon(&scase, &squest, dec_ind, tabs_to_var, &sp_sw, | |
1382 | hd_type, &force_nl); | 1383 | hd_type, &force_nl); | |
1383 | break; | 1384 | break; | |
1384 | 1385 | |||
1385 | case lbrace: /* got a '{' */ | 1386 | case lbrace: /* got a '{' */ | |
1386 | process_lbrace(&force_nl, &sp_sw, hd_type, di_stack, | 1387 | process_lbrace(&force_nl, &sp_sw, hd_type, di_stack, | |
1387 | nitems(di_stack), &dec_ind); | 1388 | (int)nitems(di_stack), &dec_ind); | |
1388 | break; | 1389 | break; | |
1389 | 1390 | |||
1390 | case rbrace: /* got a '}' */ | 1391 | case rbrace: /* got a '}' */ | |
1391 | process_rbrace(&sp_sw, &dec_ind, di_stack); | 1392 | process_rbrace(&sp_sw, &dec_ind, di_stack); | |
1392 | break; | 1393 | break; | |
1393 | 1394 | |||
1394 | case switch_expr: /* got keyword "switch" */ | 1395 | case switch_expr: /* got keyword "switch" */ | |
1395 | sp_sw = true; | 1396 | sp_sw = true; | |
1396 | hd_type = switch_expr; /* keep this for when we have seen the | 1397 | hd_type = switch_expr; /* keep this for when we have seen the | |
1397 | * expression */ | 1398 | * expression */ | |
1398 | goto copy_id; /* go move the token into buffer */ | 1399 | goto copy_id; /* go move the token into buffer */ | |
1399 | 1400 | |||
1400 | case keyword_for_if_while: | 1401 | case keyword_for_if_while: | |
1401 | sp_sw = true; /* the interesting stuff is done after the | 1402 | sp_sw = true; /* the interesting stuff is done after the | |
1402 | * expression is scanned */ | 1403 | * expression is scanned */ | |
1403 | hd_type = (*token == 'i' ? if_expr : | 1404 | hd_type = (*token == 'i' ? if_expr : | |
1404 | (*token == 'w' ? while_expr : for_exprs)); | 1405 | (*token == 'w' ? while_expr : for_exprs)); | |
1405 | 1406 | |||
1406 | /* remember the type of header for later use by parser */ | 1407 | /* remember the type of header for later use by parser */ | |
1407 | goto copy_id; /* copy the token into line */ | 1408 | goto copy_id; /* copy the token into line */ | |
1408 | 1409 | |||
1409 | case keyword_do_else: | 1410 | case keyword_do_else: | |
1410 | process_keyword_do_else(&force_nl, &last_else); | 1411 | process_keyword_do_else(&force_nl, &last_else); | |
1411 | goto copy_id; /* move the token into line */ | 1412 | goto copy_id; /* move the token into line */ | |
1412 | 1413 | |||
1413 | case type_def: | 1414 | case type_def: | |
1414 | case storage_class: | 1415 | case storage_class: | |
1415 | prefix_blankline_requested = 0; | 1416 | prefix_blankline_requested = 0; | |
1416 | goto copy_id; | 1417 | goto copy_id; | |
1417 | 1418 | |||
1418 | case keyword_struct_union_enum: | 1419 | case keyword_struct_union_enum: | |
1419 | if (ps.p_l_follow > 0) | 1420 | if (ps.p_l_follow > 0) | |
1420 | goto copy_id; | 1421 | goto copy_id; | |
1421 | /* FALLTHROUGH */ | 1422 | /* FALLTHROUGH */ | |
1422 | case decl: /* we have a declaration type (int, etc.) */ | 1423 | case decl: /* we have a declaration type (int, etc.) */ | |
1423 | process_decl(&dec_ind, &tabs_to_var); | 1424 | process_decl(&dec_ind, &tabs_to_var); | |
1424 | goto copy_id; | 1425 | goto copy_id; | |
1425 | 1426 | |||
1426 | case funcname: | 1427 | case funcname: | |
1427 | case ident: /* got an identifier or constant */ | 1428 | case ident: /* got an identifier or constant */ | |
1428 | process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl, | 1429 | process_ident(type_code, dec_ind, tabs_to_var, &sp_sw, &force_nl, | |
1429 | hd_type); | 1430 | hd_type); | |
1430 | copy_id: | 1431 | copy_id: | |
1431 | copy_id(); | 1432 | copy_id(); | |
1432 | if (type_code != funcname) | 1433 | if (type_code != funcname) | |
1433 | ps.want_blank = true; | 1434 | ps.want_blank = true; | |
1434 | break; | 1435 | break; | |
1435 | 1436 | |||
1436 | case string_prefix: | 1437 | case string_prefix: | |
1437 | process_string_prefix(); | 1438 | process_string_prefix(); | |
1438 | break; | 1439 | break; | |
1439 | 1440 | |||
1440 | case period: | 1441 | case period: | |
1441 | process_period(); | 1442 | process_period(); | |
1442 | break; | 1443 | break; | |
1443 | 1444 | |||
1444 | case comma: | 1445 | case comma: | |
1445 | process_comma(dec_ind, tabs_to_var, &force_nl); | 1446 | process_comma(dec_ind, tabs_to_var, &force_nl); | |
1446 | break; | 1447 | break; | |
1447 | 1448 | |||
1448 | case preprocessing: /* '#' */ | 1449 | case preprocessing: /* '#' */ | |
1449 | process_preprocessing(); | 1450 | process_preprocessing(); | |
1450 | break; | 1451 | break; | |
1451 | case comment: /* the initial '/' '*' or '//' of a comment */ | 1452 | case comment: /* the initial '/' '*' or '//' of a comment */ | |
1452 | process_comment(); | 1453 | process_comment(); | |
1453 | break; | 1454 | break; | |
1454 | 1455 | |||
1455 | default: | 1456 | default: | |
1456 | break; | 1457 | break; | |
1457 | } /* end of big switch stmt */ | 1458 | } /* end of big switch stmt */ | |
1458 | 1459 | |||
1459 | *e_code = '\0'; /* make sure code section is null terminated */ | 1460 | *e_code = '\0'; /* make sure code section is null terminated */ | |
1460 | if (type_code != comment && | 1461 | if (type_code != comment && | |
1461 | type_code != newline && | 1462 | type_code != newline && | |
1462 | type_code != preprocessing) | 1463 | type_code != preprocessing) | |
1463 | ps.last_token = type_code; | 1464 | ps.last_token = type_code; | |
1464 | } | 1465 | } | |
1465 | } | 1466 | } | |
1466 | 1467 | |||
1467 | int | 1468 | int | |
1468 | main(int argc, char **argv) | 1469 | main(int argc, char **argv) | |
1469 | { | 1470 | { | |
1470 | main_init_globals(); | 1471 | main_init_globals(); | |
1471 | main_parse_command_line(argc, argv); | 1472 | main_parse_command_line(argc, argv); | |
1472 | #if HAVE_CAPSICUM | 1473 | #if HAVE_CAPSICUM | |
1473 | init_capsicum(); | 1474 | init_capsicum(); | |
1474 | #endif | 1475 | #endif | |
1475 | main_prepare_parsing(); | 1476 | main_prepare_parsing(); | |
1476 | main_loop(); | 1477 | main_loop(); | |
1477 | } | 1478 | } | |
1478 | 1479 | |||
1479 | /* | 1480 | /* | |
1480 | * copy input file to backup file if in_name is /blah/blah/blah/file, then | 1481 | * copy input file to backup file if in_name is /blah/blah/blah/file, then | |
1481 | * backup file will be ".Bfile" then make the backup file the input and | 1482 | * backup file will be ".Bfile" then make the backup file the input and | |
1482 | * original input file the output | 1483 | * original input file the output | |
1483 | */ | 1484 | */ | |
1484 | static void | 1485 | static void | |
1485 | bakcopy(void) | 1486 | bakcopy(void) | |
1486 | { | 1487 | { | |
1487 | int n, | 1488 | ssize_t n; | |
1488 | bakchn; | 1489 | int bakchn; | |
1489 | char buff[8 * 1024]; | 1490 | char buff[8 * 1024]; | |
1490 | const char *p; | 1491 | const char *p; | |
1491 | 1492 | |||
1492 | /* construct file name .Bfile */ | 1493 | /* construct file name .Bfile */ | |
1493 | for (p = in_name; *p; p++); /* skip to end of string */ | 1494 | for (p = in_name; *p; p++); /* skip to end of string */ | |
1494 | while (p > in_name && *p != '/') /* find last '/' */ | 1495 | while (p > in_name && *p != '/') /* find last '/' */ | |
1495 | p--; | 1496 | p--; | |
1496 | if (*p == '/') | 1497 | if (*p == '/') | |
1497 | p++; | 1498 | p++; | |
1498 | sprintf(bakfile, "%s%s", p, simple_backup_suffix); | 1499 | sprintf(bakfile, "%s%s", p, simple_backup_suffix); | |
1499 | 1500 | |||
1500 | /* copy in_name to backup file */ | 1501 | /* copy in_name to backup file */ | |
1501 | bakchn = creat(bakfile, 0600); | 1502 | bakchn = creat(bakfile, 0600); | |
1502 | if (bakchn < 0) | 1503 | if (bakchn < 0) | |
1503 | err(1, "%s", bakfile); | 1504 | err(1, "%s", bakfile); | |
1504 | while ((n = read(fileno(input), buff, sizeof(buff))) > 0) | 1505 | while ((n = read(fileno(input), buff, sizeof(buff))) > 0) | |
1505 | if (write(bakchn, buff, n) != n) | 1506 | if (write(bakchn, buff, (size_t)n) != n) | |
1506 | err(1, "%s", bakfile); | 1507 | err(1, "%s", bakfile); | |
1507 | if (n < 0) | 1508 | if (n < 0) | |
1508 | err(1, "%s", in_name); | 1509 | err(1, "%s", in_name); | |
1509 | close(bakchn); | 1510 | close(bakchn); | |
1510 | fclose(input); | 1511 | fclose(input); | |
1511 | 1512 | |||
1512 | /* re-open backup file as the input file */ | 1513 | /* re-open backup file as the input file */ | |
1513 | input = fopen(bakfile, "r"); | 1514 | input = fopen(bakfile, "r"); | |
1514 | if (input == NULL) | 1515 | if (input == NULL) | |
1515 | err(1, "%s", bakfile); | 1516 | err(1, "%s", bakfile); | |
1516 | /* now the original input file will be the output */ | 1517 | /* now the original input file will be the output */ | |
1517 | output = fopen(in_name, "w"); | 1518 | output = fopen(in_name, "w"); | |
1518 | if (output == NULL) { | 1519 | if (output == NULL) { | |
1519 | unlink(bakfile); | 1520 | unlink(bakfile); | |
1520 | err(1, "%s", in_name); | 1521 | err(1, "%s", in_name); | |
1521 | } | 1522 | } | |
1522 | } | 1523 | } | |
1523 | 1524 | |||
1524 | static void | 1525 | static void | |
1525 | indent_declaration(int cur_dec_ind, int tabs_to_var) | 1526 | indent_declaration(int cur_dec_ind, int tabs_to_var) | |
1526 | { | 1527 | { | |
1527 | int pos = e_code - s_code; | 1528 | int pos = (int)(e_code - s_code); | |
1528 | char *startpos = e_code; | 1529 | char *startpos = e_code; | |
1529 | 1530 | |||
1530 | /* | 1531 | /* | |
1531 | * get the tab math right for indentations that are not multiples of tabsize | 1532 | * get the tab math right for indentations that are not multiples of tabsize | |
1532 | */ | 1533 | */ | |
1533 | if ((ps.ind_level * opt.indent_size) % opt.tabsize != 0) { | 1534 | if ((ps.ind_level * opt.indent_size) % opt.tabsize != 0) { | |
1534 | pos += (ps.ind_level * opt.indent_size) % opt.tabsize; | 1535 | pos += (ps.ind_level * opt.indent_size) % opt.tabsize; | |
1535 | cur_dec_ind += (ps.ind_level * opt.indent_size) % opt.tabsize; | 1536 | cur_dec_ind += (ps.ind_level * opt.indent_size) % opt.tabsize; | |
1536 | } | 1537 | } | |
1537 | if (tabs_to_var) { | 1538 | if (tabs_to_var) { | |
1538 | int tpos; | 1539 | int tpos; | |
1539 | 1540 | |||
1540 | check_size_code(cur_dec_ind / opt.tabsize); | 1541 | check_size_code(cur_dec_ind / opt.tabsize); | |
1541 | while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { | 1542 | while ((tpos = opt.tabsize * (1 + pos / opt.tabsize)) <= cur_dec_ind) { | |
1542 | *e_code++ = '\t'; | 1543 | *e_code++ = '\t'; | |
1543 | pos = tpos; | 1544 | pos = tpos; | |
1544 | } | 1545 | } | |
1545 | } | 1546 | } | |
1546 | check_size_code(cur_dec_ind - pos + 1); | 1547 | check_size_code(cur_dec_ind - pos + 1); | |
1547 | while (pos < cur_dec_ind) { | 1548 | while (pos < cur_dec_ind) { | |
1548 | *e_code++ = ' '; | 1549 | *e_code++ = ' '; | |
1549 | pos++; | 1550 | pos++; | |
1550 | } | 1551 | } | |
1551 | if (e_code == startpos && ps.want_blank) { | 1552 | if (e_code == startpos && ps.want_blank) { | |
1552 | *e_code++ = ' '; | 1553 | *e_code++ = ' '; | |
1553 | ps.want_blank = false; | 1554 | ps.want_blank = false; | |
1554 | } | 1555 | } | |
1555 | } | 1556 | } | |
1556 | 1557 | |||
1557 | #ifdef debug | 1558 | #ifdef debug | |
1558 | void | 1559 | void | |
1559 | debug_printf(const char *fmt, ...) | 1560 | debug_printf(const char *fmt, ...) | |
1560 | { | 1561 | { | |
1561 | FILE *f = output == stdout ? stderr : stdout; | 1562 | FILE *f = output == stdout ? stderr : stdout; | |
1562 | va_list ap; | 1563 | va_list ap; | |
1563 | 1564 | |||
1564 | va_start(ap, fmt); | 1565 | va_start(ap, fmt); | |
1565 | vfprintf(f, fmt, ap); | 1566 | vfprintf(f, fmt, ap); | |
1566 | va_end(ap); | 1567 | va_end(ap); | |
1567 | } | 1568 | } | |
1568 | 1569 | |||
1569 | void | 1570 | void | |
1570 | debug_println(const char *fmt, ...) | 1571 | debug_println(const char *fmt, ...) | |
1571 | { | 1572 | { | |
1572 | FILE *f = output == stdout ? stderr : stdout; | 1573 | FILE *f = output == stdout ? stderr : stdout; | |
1573 | va_list ap; | 1574 | va_list ap; | |
1574 | 1575 | |||
1575 | va_start(ap, fmt); | 1576 | va_start(ap, fmt); | |
1576 | vfprintf(f, fmt, ap); | 1577 | vfprintf(f, fmt, ap); | |
1577 | va_end(ap); | 1578 | va_end(ap); | |
1578 | fprintf(f, "\n"); | 1579 | fprintf(f, "\n"); | |
1579 | } | 1580 | } | |
1580 | 1581 | |||
1581 | void | 1582 | void | |
1582 | debug_vis_range(const char *prefix, const char *s, const char *e, | 1583 | debug_vis_range(const char *prefix, const char *s, const char *e, | |
1583 | const char *suffix) | 1584 | const char *suffix) | |
1584 | { | 1585 | { | |
1585 | debug_printf("%s", prefix); | 1586 | debug_printf("%s", prefix); | |
1586 | for (const char *p = s; p < e; p++) { | 1587 | for (const char *p = s; p < e; p++) { | |
1587 | if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') | 1588 | if (isprint((unsigned char)*p) && *p != '\\' && *p != '"') | |
1588 | debug_printf("%c", *p); | 1589 | debug_printf("%c", *p); | |
1589 | else if (*p == '\n') | 1590 | else if (*p == '\n') | |
1590 | debug_printf("\\n"); | 1591 | debug_printf("\\n"); | |
1591 | else if (*p == '\t') | 1592 | else if (*p == '\t') | |
1592 | debug_printf("\\t"); | 1593 | debug_printf("\\t"); | |
1593 | else | 1594 | else | |
1594 | debug_printf("\\x%02x", *p); | 1595 | debug_printf("\\x%02x", *p); | |
1595 | } | 1596 | } | |
1596 | debug_printf("%s", suffix); | 1597 | debug_printf("%s", suffix); | |
1597 | } | 1598 | } | |
1598 | #endif | 1599 | #endif |
--- src/usr.bin/indent/io.c 2021/03/13 18:46:39 1.47
+++ src/usr.bin/indent/io.c 2021/03/14 00:22:16 1.48
@@ -1,470 +1,470 @@ | @@ -1,470 +1,470 @@ | |||
1 | /* $NetBSD: io.c,v 1.47 2021/03/13 18:46:39 rillig Exp $ */ | 1 | /* $NetBSD: io.c,v 1.48 2021/03/14 00:22:16 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.47 2021/03/13 18:46:39 rillig Exp $"); | 49 | __RCSID("$NetBSD: io.c,v 1.48 2021/03/14 00:22:16 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_indent; | 65 | static int paren_indent; | |
66 | 66 | |||
67 | static void | 67 | static void | |
68 | output_char(char ch) | 68 | output_char(char ch) | |
69 | { | 69 | { | |
70 | fputc(ch, output); | 70 | fputc(ch, output); | |
71 | debug_vis_range("output_char '", &ch, &ch + 1, "'\n"); | 71 | debug_vis_range("output_char '", &ch, &ch + 1, "'\n"); | |
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 | debug_vis_range("output_range \"", s, e, "\"\n"); | 78 | debug_vis_range("output_range \"", s, e, "\"\n"); | |
79 | } | 79 | } | |
80 | 80 | |||
81 | static inline void | 81 | static inline void | |
82 | output_string(const char *s) | 82 | output_string(const char *s) | |
83 | { | 83 | { | |
84 | output_range(s, s + strlen(s)); | 84 | output_range(s, s + strlen(s)); | |
85 | } | 85 | } | |
86 | 86 | |||
87 | static int | 87 | static int | |
88 | output_indent(int old_ind, int new_ind) | 88 | output_indent(int old_ind, int new_ind) | |
89 | { | 89 | { | |
90 | int ind = old_ind; | 90 | int ind = old_ind; | |
91 | 91 | |||
92 | if (opt.use_tabs) { | 92 | if (opt.use_tabs) { | |
93 | int tabsize = opt.tabsize; | 93 | int tabsize = opt.tabsize; | |
94 | int n = new_ind / tabsize - ind / tabsize; | 94 | int n = new_ind / tabsize - ind / tabsize; | |
95 | if (n > 0) | 95 | if (n > 0) | |
96 | ind -= ind % tabsize; | 96 | ind -= ind % tabsize; | |
97 | for (int i = 0; i < n; i++) { | 97 | for (int i = 0; i < n; i++) { | |
98 | fputc('\t', output); | 98 | fputc('\t', output); | |
99 | ind += tabsize; | 99 | ind += tabsize; | |
100 | } | 100 | } | |
101 | } | 101 | } | |
102 | 102 | |||
103 | for (; ind < new_ind; ind++) | 103 | for (; ind < new_ind; ind++) | |
104 | fputc(' ', output); | 104 | fputc(' ', output); | |
105 | 105 | |||
106 | debug_println("output_indent %d", ind); | 106 | debug_println("output_indent %d", ind); | |
107 | return ind; | 107 | return ind; | |
108 | } | 108 | } | |
109 | 109 | |||
110 | /* | 110 | /* | |
111 | * dump_line is the routine that actually effects the printing of the new | 111 | * dump_line is the routine that actually effects the printing of the new | |
112 | * source. It prints the label section, followed by the code section with | 112 | * source. It prints the label section, followed by the code section with | |
113 | * the appropriate nesting level, followed by any comments. | 113 | * the appropriate nesting level, followed by any comments. | |
114 | */ | 114 | */ | |
115 | void | 115 | void | |
116 | dump_line(void) | 116 | dump_line(void) | |
117 | { | 117 | { | |
118 | int cur_col; | 118 | int cur_col; | |
119 | static int not_first_line; | 119 | static int not_first_line; | |
120 | 120 | |||
121 | if (ps.procname[0]) { | 121 | if (ps.procname[0]) { | |
122 | ps.ind_level = 0; | 122 | ps.ind_level = 0; | |
123 | ps.procname[0] = 0; | 123 | ps.procname[0] = 0; | |
124 | } | 124 | } | |
125 | 125 | |||
126 | if (s_code == e_code && s_lab == e_lab && s_com == e_com) { | 126 | if (s_code == e_code && s_lab == e_lab && s_com == e_com) { | |
127 | if (suppress_blanklines > 0) | 127 | if (suppress_blanklines > 0) | |
128 | suppress_blanklines--; | 128 | suppress_blanklines--; | |
129 | else { | 129 | else { | |
130 | ps.bl_line = true; | 130 | ps.bl_line = true; | |
131 | n_real_blanklines++; | 131 | n_real_blanklines++; | |
132 | } | 132 | } | |
133 | } else if (!inhibit_formatting) { | 133 | } else if (!inhibit_formatting) { | |
134 | suppress_blanklines = 0; | 134 | suppress_blanklines = 0; | |
135 | ps.bl_line = false; | 135 | ps.bl_line = false; | |
136 | if (prefix_blankline_requested && not_first_line) { | 136 | if (prefix_blankline_requested && not_first_line) { | |
137 | if (opt.swallow_optional_blanklines) { | 137 | if (opt.swallow_optional_blanklines) { | |
138 | if (n_real_blanklines == 1) | 138 | if (n_real_blanklines == 1) | |
139 | n_real_blanklines = 0; | 139 | n_real_blanklines = 0; | |
140 | } else { | 140 | } else { | |
141 | if (n_real_blanklines == 0) | 141 | if (n_real_blanklines == 0) | |
142 | n_real_blanklines = 1; | 142 | n_real_blanklines = 1; | |
143 | } | 143 | } | |
144 | } | 144 | } | |
145 | while (--n_real_blanklines >= 0) | 145 | while (--n_real_blanklines >= 0) | |
146 | output_char('\n'); | 146 | output_char('\n'); | |
147 | n_real_blanklines = 0; | 147 | n_real_blanklines = 0; | |
148 | if (ps.ind_level == 0) | 148 | if (ps.ind_level == 0) | |
149 | ps.ind_stmt = 0; /* this is a class A kludge. dont do | 149 | ps.ind_stmt = 0; /* this is a class A kludge. dont do | |
150 | * additional statement indentation if we are | 150 | * additional statement indentation if we are | |
151 | * at bracket level 0 */ | 151 | * at bracket level 0 */ | |
152 | 152 | |||
153 | if (e_lab != s_lab || e_code != s_code) | 153 | if (e_lab != s_lab || e_code != s_code) | |
154 | ++code_lines; /* keep count of lines with code */ | 154 | ++code_lines; /* keep count of lines with code */ | |
155 | 155 | |||
156 | 156 | |||
157 | if (e_lab != s_lab) { /* print lab, if any */ | 157 | if (e_lab != s_lab) { /* print lab, if any */ | |
158 | if (comment_open) { | 158 | if (comment_open) { | |
159 | comment_open = 0; | 159 | comment_open = 0; | |
160 | output_string(".*/\n"); | 160 | output_string(".*/\n"); | |
161 | } | 161 | } | |
162 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | 162 | while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t')) | |
163 | e_lab--; | 163 | e_lab--; | |
164 | *e_lab = '\0'; | 164 | *e_lab = '\0'; | |
165 | cur_col = 1 + output_indent(0, compute_label_indent()); | 165 | cur_col = 1 + output_indent(0, compute_label_indent()); | |
166 | if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 | 166 | if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0 | |
167 | || strncmp(s_lab, "#endif", 6) == 0)) { | 167 | || strncmp(s_lab, "#endif", 6) == 0)) { | |
168 | char *s = s_lab; | 168 | char *s = s_lab; | |
169 | if (e_lab[-1] == '\n') e_lab--; | 169 | if (e_lab[-1] == '\n') e_lab--; | |
170 | do { | 170 | do { | |
171 | output_char(*s++); | 171 | output_char(*s++); | |
172 | } while (s < e_lab && 'a' <= *s && *s <= 'z'); | 172 | } while (s < e_lab && 'a' <= *s && *s <= 'z'); | |
173 | while ((*s == ' ' || *s == '\t') && s < e_lab) | 173 | while ((*s == ' ' || *s == '\t') && s < e_lab) | |
174 | s++; | 174 | s++; | |
175 | if (s < e_lab) { | 175 | if (s < e_lab) { | |
176 | if (s[0] == '/' && s[1] == '*') { | 176 | if (s[0] == '/' && s[1] == '*') { | |
177 | output_char('\t'); | 177 | output_char('\t'); | |
178 | output_range(s, e_lab); | 178 | output_range(s, e_lab); | |
179 | } else { | 179 | } else { | |
180 | output_string("\t/* "); | 180 | output_string("\t/* "); | |
181 | output_range(s, e_lab); | 181 | output_range(s, e_lab); | |
182 | output_string(" */"); | 182 | output_string(" */"); | |
183 | } | 183 | } | |
184 | } | 184 | } | |
185 | } else | 185 | } else | |
186 | output_range(s_lab, e_lab); | 186 | output_range(s_lab, e_lab); | |
187 | cur_col = 1 + indentation_after(cur_col - 1, s_lab); | 187 | cur_col = 1 + indentation_after(cur_col - 1, s_lab); | |
188 | } else | 188 | } else | |
189 | cur_col = 1; /* there is no label section */ | 189 | cur_col = 1; /* there is no label section */ | |
190 | 190 | |||
191 | ps.pcase = false; | 191 | ps.pcase = false; | |
192 | 192 | |||
193 | if (s_code != e_code) { /* print code section, if any */ | 193 | if (s_code != e_code) { /* print code section, if any */ | |
194 | if (comment_open) { | 194 | if (comment_open) { | |
195 | comment_open = 0; | 195 | comment_open = 0; | |
196 | output_string(".*/\n"); | 196 | output_string(".*/\n"); | |
197 | } | 197 | } | |
198 | int target_col = 1 + compute_code_indent(); | 198 | int target_col = 1 + compute_code_indent(); | |
199 | { | 199 | { | |
200 | int i; | 200 | int i; | |
201 | 201 | |||
202 | for (i = 0; i < ps.p_l_follow; i++) { | 202 | for (i = 0; i < ps.p_l_follow; i++) { | |
203 | if (ps.paren_indents[i] >= 0) { | 203 | if (ps.paren_indents[i] >= 0) { | |
204 | int ind = ps.paren_indents[i]; | 204 | int ind = ps.paren_indents[i]; | |
205 | /* | 205 | /* | |
206 | * XXX: this mix of 'indent' and 'column' smells like | 206 | * XXX: this mix of 'indent' and 'column' smells like | |
207 | * an off-by-one error. | 207 | * an off-by-one error. | |
208 | */ | 208 | */ | |
209 | ps.paren_indents[i] = -(ind + target_col); | 209 | ps.paren_indents[i] = -(ind + target_col); | |
210 | debug_println( | 210 | debug_println( | |
211 | "setting pi[%d] from %d to %d for column %d", | 211 | "setting pi[%d] from %d to %d for column %d", | |
212 | i, ind, ps.paren_indents[i], target_col); | 212 | i, ind, ps.paren_indents[i], target_col); | |
213 | } | 213 | } | |
214 | } | 214 | } | |
215 | } | 215 | } | |
216 | cur_col = 1 + output_indent(cur_col - 1, target_col - 1); | 216 | cur_col = 1 + output_indent(cur_col - 1, target_col - 1); | |
217 | output_range(s_code, e_code); | 217 | output_range(s_code, e_code); | |
218 | cur_col = 1 + indentation_after(cur_col - 1, s_code); | 218 | cur_col = 1 + indentation_after(cur_col - 1, s_code); | |
219 | } | 219 | } | |
220 | if (s_com != e_com) { /* print comment, if any */ | 220 | if (s_com != e_com) { /* print comment, if any */ | |
221 | int target_col = ps.com_col; | 221 | int target_col = ps.com_col; | |
222 | char *com_st = s_com; | 222 | char *com_st = s_com; | |
223 | 223 | |||
224 | target_col += ps.comment_delta; | 224 | target_col += ps.comment_delta; | |
225 | while (*com_st == '\t') /* consider original indentation in | 225 | while (*com_st == '\t') /* consider original indentation in | |
226 | * case this is a box comment */ | 226 | * case this is a box comment */ | |
227 | com_st++, target_col += opt.tabsize; | 227 | com_st++, target_col += opt.tabsize; | |
228 | while (target_col <= 0) | 228 | while (target_col <= 0) | |
229 | if (*com_st == ' ') | 229 | if (*com_st == ' ') | |
230 | target_col++, com_st++; | 230 | target_col++, com_st++; | |
231 | else if (*com_st == '\t') { | 231 | else if (*com_st == '\t') { | |
232 | target_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; | 232 | target_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; | |
233 | com_st++; | 233 | com_st++; | |
234 | } else | 234 | } else | |
235 | target_col = 1; | 235 | target_col = 1; | |
236 | if (cur_col > target_col) { /* if comment can't fit on this line, | 236 | if (cur_col > target_col) { /* if comment can't fit on this line, | |
237 | * put it on next line */ | 237 | * put it on next line */ | |
238 | output_char('\n'); | 238 | output_char('\n'); | |
239 | cur_col = 1; | 239 | cur_col = 1; | |
240 | ++ps.out_lines; | 240 | ++ps.out_lines; | |
241 | } | 241 | } | |
242 | while (e_com > com_st && isspace((unsigned char)e_com[-1])) | 242 | while (e_com > com_st && isspace((unsigned char)e_com[-1])) | |
243 | e_com--; | 243 | e_com--; | |
244 | (void)output_indent(cur_col - 1, target_col - 1); | 244 | (void)output_indent(cur_col - 1, target_col - 1); | |
245 | output_range(com_st, e_com); | 245 | output_range(com_st, e_com); | |
246 | ps.comment_delta = ps.n_comment_delta; | 246 | ps.comment_delta = ps.n_comment_delta; | |
247 | ++ps.com_lines; /* count lines with comments */ | 247 | ++ps.com_lines; /* count lines with comments */ | |
248 | } | 248 | } | |
249 | if (ps.use_ff) | 249 | if (ps.use_ff) | |
250 | output_char('\014'); | 250 | output_char('\014'); | |
251 | else | 251 | else | |
252 | output_char('\n'); | 252 | output_char('\n'); | |
253 | ++ps.out_lines; | 253 | ++ps.out_lines; | |
254 | if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { | 254 | if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) { | |
255 | prefix_blankline_requested = 1; | 255 | prefix_blankline_requested = 1; | |
256 | ps.just_saw_decl = 0; | 256 | ps.just_saw_decl = 0; | |
257 | } else | 257 | } else | |
258 | prefix_blankline_requested = postfix_blankline_requested; | 258 | prefix_blankline_requested = postfix_blankline_requested; | |
259 | postfix_blankline_requested = 0; | 259 | postfix_blankline_requested = 0; | |
260 | } | 260 | } | |
261 | 261 | |||
262 | /* keep blank lines after '//' comments */ | 262 | /* keep blank lines after '//' comments */ | |
263 | if (e_com - s_com > 1 && s_com[1] == '/') | 263 | if (e_com - s_com > 1 && s_com[1] == '/') | |
264 | output_range(s_token, e_token); | 264 | output_range(s_token, e_token); | |
265 | 265 | |||
266 | ps.decl_on_line = ps.in_decl; /* if we are in the middle of a declaration, | 266 | ps.decl_on_line = ps.in_decl; /* if we are in the middle of a declaration, | |
267 | * remember that fact for proper comment | 267 | * remember that fact for proper comment | |
268 | * indentation */ | 268 | * indentation */ | |
269 | ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be indented if | 269 | ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be indented if | |
270 | * we have not completed this stmt and if we | 270 | * we have not completed this stmt and if we | |
271 | * are not in the middle of a declaration */ | 271 | * are not in the middle of a declaration */ | |
272 | ps.use_ff = false; | 272 | ps.use_ff = false; | |
273 | ps.dumped_decl_indent = 0; | 273 | ps.dumped_decl_indent = 0; | |
274 | *(e_lab = s_lab) = '\0'; /* reset buffers */ | 274 | *(e_lab = s_lab) = '\0'; /* reset buffers */ | |
275 | *(e_code = s_code) = '\0'; | 275 | *(e_code = s_code) = '\0'; | |
276 | *(e_com = s_com = combuf + 1) = '\0'; | 276 | *(e_com = s_com = combuf + 1) = '\0'; | |
277 | ps.ind_level = ps.i_l_follow; | 277 | ps.ind_level = ps.i_l_follow; | |
278 | ps.paren_level = ps.p_l_follow; | 278 | ps.paren_level = ps.p_l_follow; | |
279 | if (ps.paren_level > 0) { | 279 | if (ps.paren_level > 0) { | |
280 | /* TODO: explain what negative indentation means */ | 280 | /* TODO: explain what negative indentation means */ | |
281 | paren_indent = -ps.paren_indents[ps.paren_level - 1]; | 281 | paren_indent = -ps.paren_indents[ps.paren_level - 1]; | |
282 | debug_println("paren_indent is now %d", paren_indent); | 282 | debug_println("paren_indent is now %d", paren_indent); | |
283 | } | 283 | } | |
284 | not_first_line = 1; | 284 | not_first_line = 1; | |
285 | } | 285 | } | |
286 | 286 | |||
287 | int | 287 | int | |
288 | compute_code_indent(void) | 288 | compute_code_indent(void) | |
289 | { | 289 | { | |
290 | int target_ind = opt.indent_size * ps.ind_level; | 290 | int target_ind = opt.indent_size * ps.ind_level; | |
291 | 291 | |||
292 | if (ps.paren_level != 0) { | 292 | if (ps.paren_level != 0) { | |
293 | if (!opt.lineup_to_parens) | 293 | if (!opt.lineup_to_parens) | |
294 | target_ind += opt.continuation_indent * | 294 | target_ind += opt.continuation_indent * | |
295 | (2 * opt.continuation_indent == opt.indent_size ? 1 : ps.paren_level); | 295 | (2 * opt.continuation_indent == opt.indent_size ? 1 : ps.paren_level); | |
296 | else if (opt.lineup_to_parens_always) | 296 | else if (opt.lineup_to_parens_always) | |
297 | /* | 297 | /* | |
298 | * XXX: where does this '- 1' come from? It looks strange but is | 298 | * XXX: where does this '- 1' come from? It looks strange but is | |
299 | * nevertheless needed for proper indentation, as demonstrated in | 299 | * nevertheless needed for proper indentation, as demonstrated in | |
300 | * the test opt-lpl.0. | 300 | * the test opt-lpl.0. | |
301 | */ | 301 | */ | |
302 | target_ind = paren_indent - 1; | 302 | target_ind = paren_indent - 1; | |
303 | else { | 303 | else { | |
304 | int w; | 304 | int w; | |
305 | int t = paren_indent; | 305 | int t = paren_indent; | |
306 | 306 | |||
307 | if ((w = 1 + indentation_after(t - 1, s_code) - opt.max_line_length) > 0 | 307 | if ((w = 1 + indentation_after(t - 1, s_code) - opt.max_line_length) > 0 | |
308 | && 1 + indentation_after(target_ind, s_code) <= opt.max_line_length) { | 308 | && 1 + indentation_after(target_ind, s_code) <= opt.max_line_length) { | |
309 | t -= w + 1; | 309 | t -= w + 1; | |
310 | if (t > target_ind + 1) | 310 | if (t > target_ind + 1) | |
311 | target_ind = t - 1; | 311 | target_ind = t - 1; | |
312 | } else | 312 | } else | |
313 | target_ind = t - 1; | 313 | target_ind = t - 1; | |
314 | } | 314 | } | |
315 | } else if (ps.ind_stmt) | 315 | } else if (ps.ind_stmt) | |
316 | target_ind += opt.continuation_indent; | 316 | target_ind += opt.continuation_indent; | |
317 | return target_ind; | 317 | return target_ind; | |
318 | } | 318 | } | |
319 | 319 | |||
320 | int | 320 | int | |
321 | compute_label_indent(void) | 321 | compute_label_indent(void) | |
322 | { | 322 | { | |
323 | if (ps.pcase) | 323 | if (ps.pcase) | |
324 | return (int) (case_ind * opt.indent_size); | 324 | return (int) (case_ind * opt.indent_size); | |
325 | if (s_lab[0] == '#') | 325 | if (s_lab[0] == '#') | |
326 | return 0; | 326 | return 0; | |
327 | return opt.indent_size * (ps.ind_level - label_offset); | 327 | return opt.indent_size * (ps.ind_level - label_offset); | |
328 | } | 328 | } | |
329 | 329 | |||
330 | 330 | |||
331 | /* | 331 | /* | |
332 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | 332 | * Copyright (C) 1976 by the Board of Trustees of the University of Illinois | |
333 | * | 333 | * | |
334 | * All rights reserved | 334 | * All rights reserved | |
335 | * | 335 | * | |
336 | * FUNCTION: Reads one block of input into the input buffer | 336 | * FUNCTION: Reads one block of input into the input buffer | |
337 | */ | 337 | */ | |
338 | void | 338 | void | |
339 | fill_buffer(void) | 339 | fill_buffer(void) | |
340 | { /* this routine reads stuff from the input */ | 340 | { /* this routine reads stuff from the input */ | |
341 | char *p; | 341 | char *p; | |
342 | int i; | 342 | int i; | |
343 | FILE *f = input; | 343 | FILE *f = input; | |
344 | 344 | |||
345 | if (bp_save != NULL) { /* there is a partly filled input buffer left */ | 345 | if (bp_save != NULL) { /* there is a partly filled input buffer left */ | |
346 | buf_ptr = bp_save; /* do not read anything, just switch buffers */ | 346 | buf_ptr = bp_save; /* do not read anything, just switch buffers */ | |
347 | buf_end = be_save; | 347 | buf_end = be_save; | |
348 | bp_save = be_save = NULL; | 348 | bp_save = be_save = NULL; | |
349 | debug_println("switched buf_ptr back to bp_save"); | 349 | debug_println("switched buf_ptr back to bp_save"); | |
350 | if (buf_ptr < buf_end) | 350 | if (buf_ptr < buf_end) | |
351 | return; /* only return if there is really something in | 351 | return; /* only return if there is really something in | |
352 | * this buffer */ | 352 | * this buffer */ | |
353 | } | 353 | } | |
354 | for (p = in_buffer;;) { | 354 | for (p = in_buffer;;) { | |
355 | if (p >= in_buffer_limit) { | 355 | if (p >= in_buffer_limit) { | |
356 | int size = (in_buffer_limit - in_buffer) * 2 + 10; | 356 | size_t size = (in_buffer_limit - in_buffer) * 2 + 10; | |
357 | int offset = p - in_buffer; | 357 | size_t offset = p - in_buffer; | |
358 | in_buffer = realloc(in_buffer, size); | 358 | in_buffer = realloc(in_buffer, size); | |
359 | if (in_buffer == NULL) | 359 | if (in_buffer == NULL) | |
360 | errx(1, "input line too long"); | 360 | errx(1, "input line too long"); | |
361 | p = in_buffer + offset; | 361 | p = in_buffer + offset; | |
362 | in_buffer_limit = in_buffer + size - 2; | 362 | in_buffer_limit = in_buffer + size - 2; | |
363 | } | 363 | } | |
364 | if ((i = getc(f)) == EOF) { | 364 | if ((i = getc(f)) == EOF) { | |
365 | *p++ = ' '; | 365 | *p++ = ' '; | |
366 | *p++ = '\n'; | 366 | *p++ = '\n'; | |
367 | had_eof = true; | 367 | had_eof = true; | |
368 | break; | 368 | break; | |
369 | } | 369 | } | |
370 | if (i != '\0') | 370 | if (i != '\0') | |
371 | *p++ = i; | 371 | *p++ = i; | |
372 | if (i == '\n') | 372 | if (i == '\n') | |
373 | break; | 373 | break; | |
374 | } | 374 | } | |
375 | buf_ptr = in_buffer; | 375 | buf_ptr = in_buffer; | |
376 | buf_end = p; | 376 | buf_end = p; | |
377 | if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { | 377 | if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') { | |
378 | if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) | 378 | if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0) | |
379 | fill_buffer(); /* flush indent error message */ | 379 | fill_buffer(); /* flush indent error message */ | |
380 | else { | 380 | else { | |
381 | int com = 0; | 381 | int com = 0; | |
382 | 382 | |||
383 | p = in_buffer; | 383 | p = in_buffer; | |
384 | while (*p == ' ' || *p == '\t') | 384 | while (*p == ' ' || *p == '\t') | |
385 | p++; | 385 | p++; | |
386 | if (*p == '/' && p[1] == '*') { | 386 | if (*p == '/' && p[1] == '*') { | |
387 | p += 2; | 387 | p += 2; | |
388 | while (*p == ' ' || *p == '\t') | 388 | while (*p == ' ' || *p == '\t') | |
389 | p++; | 389 | p++; | |
390 | if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E' | 390 | if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E' | |
391 | && p[4] == 'N' && p[5] == 'T') { | 391 | && p[4] == 'N' && p[5] == 'T') { | |
392 | p += 6; | 392 | p += 6; | |
393 | while (*p == ' ' || *p == '\t') | 393 | while (*p == ' ' || *p == '\t') | |
394 | p++; | 394 | p++; | |
395 | if (*p == '*') | 395 | if (*p == '*') | |
396 | com = 1; | 396 | com = 1; | |
397 | else if (*p == 'O') { | 397 | else if (*p == 'O') { | |
398 | if (*++p == 'N') | 398 | if (*++p == 'N') | |
399 | p++, com = 1; | 399 | p++, com = 1; | |
400 | else if (*p == 'F' && *++p == 'F') | 400 | else if (*p == 'F' && *++p == 'F') | |
401 | p++, com = 2; | 401 | p++, com = 2; | |
402 | } | 402 | } | |
403 | while (*p == ' ' || *p == '\t') | 403 | while (*p == ' ' || *p == '\t') | |
404 | p++; | 404 | p++; | |
405 | if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { | 405 | if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) { | |
406 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | 406 | if (s_com != e_com || s_lab != e_lab || s_code != e_code) | |
407 | dump_line(); | 407 | dump_line(); | |
408 | if (!(inhibit_formatting = com - 1)) { | 408 | if (!(inhibit_formatting = com - 1)) { | |
409 | n_real_blanklines = 0; | 409 | n_real_blanklines = 0; | |
410 | postfix_blankline_requested = 0; | 410 | postfix_blankline_requested = 0; | |
411 | prefix_blankline_requested = 0; | 411 | prefix_blankline_requested = 0; | |
412 | suppress_blanklines = 1; | 412 | suppress_blanklines = 1; | |
413 | } | 413 | } | |
414 | } | 414 | } | |
415 | } | 415 | } | |
416 | } | 416 | } | |
417 | } | 417 | } | |
418 | } | 418 | } | |
419 | if (inhibit_formatting) { | 419 | if (inhibit_formatting) { | |
420 | p = in_buffer; | 420 | p = in_buffer; | |
421 | do { | 421 | do { | |
422 | output_char(*p); | 422 | output_char(*p); | |
423 | } while (*p++ != '\n'); | 423 | } while (*p++ != '\n'); | |
424 | } | 424 | } | |
425 | } | 425 | } | |
426 | 426 | |||
427 | int | 427 | int | |
428 | indentation_after_range(int ind, const char *start, const char *end) | 428 | indentation_after_range(int ind, const char *start, const char *end) | |
429 | { | 429 | { | |
430 | for (const char *p = start; *p != '\0' && p != end; ++p) { | 430 | for (const char *p = start; *p != '\0' && p != end; ++p) { | |
431 | if (*p == '\n' || *p == '\f') | 431 | if (*p == '\n' || *p == '\f') | |
432 | ind = 0; | 432 | ind = 0; | |
433 | else if (*p == '\t') | 433 | else if (*p == '\t') | |
434 | ind = opt.tabsize * (ind / opt.tabsize + 1); | 434 | ind = opt.tabsize * (ind / opt.tabsize + 1); | |
435 | else if (*p == '\b') | 435 | else if (*p == '\b') | |
436 | --ind; | 436 | --ind; | |
437 | else | 437 | else | |
438 | ++ind; | 438 | ++ind; | |
439 | } | 439 | } | |
440 | return ind; | 440 | return ind; | |
441 | } | 441 | } | |
442 | 442 | |||
443 | int | 443 | int | |
444 | indentation_after(int ind, const char *s) | 444 | indentation_after(int ind, const char *s) | |
445 | { | 445 | { | |
446 | return indentation_after_range(ind, s, NULL); | 446 | return indentation_after_range(ind, s, NULL); | |
447 | } | 447 | } | |
448 | 448 | |||
449 | void | 449 | void | |
450 | diag(int level, const char *msg, ...) | 450 | diag(int level, const char *msg, ...) | |
451 | { | 451 | { | |
452 | va_list ap; | 452 | va_list ap; | |
453 | const char *s, *e; | 453 | const char *s, *e; | |
454 | 454 | |||
455 | if (level) | 455 | if (level) | |
456 | found_err = 1; | 456 | found_err = 1; | |
457 | 457 | |||
458 | if (output == stdout) { | 458 | if (output == stdout) { | |
459 | s = "/**INDENT** "; | 459 | s = "/**INDENT** "; | |
460 | e = " */"; | 460 | e = " */"; | |
461 | } else { | 461 | } else { | |
462 | s = e = ""; | 462 | s = e = ""; | |
463 | } | 463 | } | |
464 | 464 | |||
465 | va_start(ap, msg); | 465 | va_start(ap, msg); | |
466 | fprintf(stderr, "%s%s@%d: ", s, level == 0 ? "Warning" : "Error", line_no); | 466 | fprintf(stderr, "%s%s@%d: ", s, level == 0 ? "Warning" : "Error", line_no); | |
467 | vfprintf(stderr, msg, ap); | 467 | vfprintf(stderr, msg, ap); | |
468 | fprintf(stderr, "%s\n", e); | 468 | fprintf(stderr, "%s\n", e); | |
469 | va_end(ap); | 469 | va_end(ap); | |
470 | } | 470 | } |
--- src/usr.bin/indent/lexi.c 2021/03/13 11:27:01 1.40
+++ src/usr.bin/indent/lexi.c 2021/03/14 00:22:16 1.41
@@ -1,720 +1,720 @@ | @@ -1,720 +1,720 @@ | |||
1 | /* $NetBSD: lexi.c,v 1.40 2021/03/13 11:27:01 rillig Exp $ */ | 1 | /* $NetBSD: lexi.c,v 1.41 2021/03/14 00:22:16 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.40 2021/03/13 11:27:01 rillig Exp $"); | 49 | __RCSID("$NetBSD: lexi.c,v 1.41 2021/03/14 00:22:16 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 | debug_printf(" %s ", name); | 265 | debug_printf(" %s ", name); | |
266 | debug_vis_range("\"", s, e, "\""); | 266 | debug_vis_range("\"", s, e, "\""); | |
267 | } | 267 | } | |
268 | } | 268 | } | |
269 | 269 | |||
270 | static token_type | 270 | static token_type | |
271 | lexi_end(token_type code) | 271 | lexi_end(token_type code) | |
272 | { | 272 | { | |
273 | debug_printf("in line %d, lexi returns '%s'", | 273 | debug_printf("in line %d, lexi returns '%s'", | |
274 | line_no, token_type_name(code)); | 274 | line_no, token_type_name(code)); | |
275 | print_buf("token", s_token, e_token); | 275 | print_buf("token", s_token, e_token); | |
276 | print_buf("label", s_lab, e_lab); | 276 | print_buf("label", s_lab, e_lab); | |
277 | print_buf("code", s_code, e_code); | 277 | print_buf("code", s_code, e_code); | |
278 | print_buf("comment", s_com, e_com); | 278 | print_buf("comment", s_com, e_com); | |
279 | debug_printf("\n"); | 279 | debug_printf("\n"); | |
280 | 280 | |||
281 | return code; | 281 | return code; | |
282 | } | 282 | } | |
283 | #else | 283 | #else | |
284 | # define lexi_end(tk) (tk) | 284 | # define lexi_end(tk) (tk) | |
285 | #endif | 285 | #endif | |
286 | 286 | |||
287 | token_type | 287 | token_type | |
288 | lexi(struct parser_state *state) | 288 | lexi(struct parser_state *state) | |
289 | { | 289 | { | |
290 | int unary_delim; /* this is set to 1 if the current token | 290 | int unary_delim; /* this is set to 1 if the current token | |
291 | * forces a following operator to be unary */ | 291 | * forces a following operator to be unary */ | |
292 | token_type code; /* internal code to be returned */ | 292 | token_type code; /* internal code to be returned */ | |
293 | char qchar; /* the delimiter character for a string */ | 293 | char qchar; /* the delimiter character for a string */ | |
294 | 294 | |||
295 | e_token = s_token; /* point to start of place to save token */ | 295 | e_token = s_token; /* point to start of place to save token */ | |
296 | unary_delim = false; | 296 | unary_delim = false; | |
297 | state->col_1 = state->last_nl; /* tell world that this token started | 297 | state->col_1 = state->last_nl; /* tell world that this token started | |
298 | * in column 1 iff the last thing | 298 | * in column 1 iff the last thing | |
299 | * scanned was a newline */ | 299 | * scanned was a newline */ | |
300 | state->last_nl = false; | 300 | state->last_nl = false; | |
301 | 301 | |||
302 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ | 302 | while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */ | |
303 | state->col_1 = false; /* leading blanks imply token is not in column | 303 | state->col_1 = false; /* leading blanks imply token is not in column | |
304 | * 1 */ | 304 | * 1 */ | |
305 | inbuf_skip(); | 305 | inbuf_skip(); | |
306 | } | 306 | } | |
307 | 307 | |||
308 | /* Scan an alphanumeric token */ | 308 | /* Scan an alphanumeric token */ | |
309 | if (isalnum((unsigned char)*buf_ptr) || | 309 | if (isalnum((unsigned char)*buf_ptr) || | |
310 | *buf_ptr == '_' || *buf_ptr == '$' || | 310 | *buf_ptr == '_' || *buf_ptr == '$' || | |
311 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | 311 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | |
312 | /* | 312 | /* | |
313 | * we have a character or number | 313 | * we have a character or number | |
314 | */ | 314 | */ | |
315 | struct templ *p; | 315 | struct templ *p; | |
316 | 316 | |||
317 | if (isdigit((unsigned char)*buf_ptr) || | 317 | if (isdigit((unsigned char)*buf_ptr) || | |
318 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | 318 | (buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) { | |
319 | char s; | 319 | char s; | |
320 | unsigned char i; | 320 | unsigned char i; | |
321 | 321 | |||
322 | for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) { | 322 | for (s = 'A'; s != 'f' && s != 'i' && s != 'u'; ) { | |
323 | i = (unsigned char)*buf_ptr; | 323 | i = (unsigned char)*buf_ptr; | |
324 | if (i >= nitems(table) || table[i] == NULL || | 324 | if (i >= nitems(table) || table[i] == NULL || | |
325 | table[i][s - 'A'] == ' ') { | 325 | table[i][s - 'A'] == ' ') { | |
326 | s = table[0][s - 'A']; | 326 | s = table[0][s - 'A']; | |
327 | break; | 327 | break; | |
328 | } | 328 | } | |
329 | s = table[i][s - 'A']; | 329 | s = table[i][s - 'A']; | |
330 | check_size_token(1); | 330 | check_size_token(1); | |
331 | *e_token++ = inbuf_next(); | 331 | *e_token++ = inbuf_next(); | |
332 | } | 332 | } | |
333 | /* s now indicates the type: f(loating), i(integer), u(nknown) */ | 333 | /* s now indicates the type: f(loating), i(integer), u(nknown) */ | |
334 | } else { | 334 | } else { | |
335 | while (isalnum((unsigned char)*buf_ptr) || | 335 | while (isalnum((unsigned char)*buf_ptr) || | |
336 | *buf_ptr == '\\' || | 336 | *buf_ptr == '\\' || | |
337 | *buf_ptr == '_' || *buf_ptr == '$') { | 337 | *buf_ptr == '_' || *buf_ptr == '$') { | |
338 | /* fill_buffer() terminates buffer with newline */ | 338 | /* fill_buffer() terminates buffer with newline */ | |
339 | if (*buf_ptr == '\\') { | 339 | if (*buf_ptr == '\\') { | |
340 | if (buf_ptr[1] == '\n') { | 340 | if (buf_ptr[1] == '\n') { | |
341 | buf_ptr += 2; | 341 | buf_ptr += 2; | |
342 | if (buf_ptr >= buf_end) | 342 | if (buf_ptr >= buf_end) | |
343 | fill_buffer(); | 343 | fill_buffer(); | |
344 | } else | 344 | } else | |
345 | break; | 345 | break; | |
346 | } | 346 | } | |
347 | check_size_token(1); | 347 | check_size_token(1); | |
348 | *e_token++ = inbuf_next(); | 348 | *e_token++ = inbuf_next(); | |
349 | } | 349 | } | |
350 | } | 350 | } | |
351 | *e_token = '\0'; | 351 | *e_token = '\0'; | |
352 | 352 | |||
353 | if (s_token[0] == 'L' && s_token[1] == '\0' && | 353 | if (s_token[0] == 'L' && s_token[1] == '\0' && | |
354 | (*buf_ptr == '"' || *buf_ptr == '\'')) | 354 | (*buf_ptr == '"' || *buf_ptr == '\'')) | |
355 | return lexi_end(string_prefix); | 355 | return lexi_end(string_prefix); | |
356 | 356 | |||
357 | while (*buf_ptr == ' ' || *buf_ptr == '\t') /* get rid of blanks */ | 357 | while (*buf_ptr == ' ' || *buf_ptr == '\t') /* get rid of blanks */ | |
358 | inbuf_next(); | 358 | inbuf_next(); | |
359 | state->keyword = rw_0; | 359 | state->keyword = rw_0; | |
360 | if (state->last_token == keyword_struct_union_enum && | 360 | if (state->last_token == keyword_struct_union_enum && | |
361 | !state->p_l_follow) { | 361 | !state->p_l_follow) { | |
362 | /* if last token was 'struct' and we're not in parentheses, then | 362 | /* if last token was 'struct' and we're not in parentheses, then | |
363 | * this token should be treated as a declaration */ | 363 | * this token should be treated as a declaration */ | |
364 | state->last_u_d = true; | 364 | state->last_u_d = true; | |
365 | return lexi_end(decl); | 365 | return lexi_end(decl); | |
366 | } | 366 | } | |
367 | /* | 367 | /* | |
368 | * Operator after identifier is binary unless last token was 'struct' | 368 | * Operator after identifier is binary unless last token was 'struct' | |
369 | */ | 369 | */ | |
370 | state->last_u_d = (state->last_token == keyword_struct_union_enum); | 370 | state->last_u_d = (state->last_token == keyword_struct_union_enum); | |
371 | 371 | |||
372 | p = bsearch(s_token, specials, sizeof specials / sizeof specials[0], | 372 | p = bsearch(s_token, specials, sizeof specials / sizeof specials[0], | |
373 | sizeof specials[0], compare_templ_array); | 373 | sizeof specials[0], compare_templ_array); | |
374 | if (p == NULL) { /* not a special keyword... */ | 374 | if (p == NULL) { /* not a special keyword... */ | |
375 | char *u; | 375 | char *u; | |
376 | 376 | |||
377 | /* ... so maybe a type_t or a typedef */ | 377 | /* ... so maybe a type_t or a typedef */ | |
378 | if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && | 378 | if ((opt.auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) && | |
379 | strcmp(u, "_t") == 0) || (typename_top >= 0 && | 379 | strcmp(u, "_t") == 0) || (typename_top >= 0 && | |
380 | bsearch(s_token, typenames, typename_top + 1, | 380 | bsearch(s_token, typenames, typename_top + 1, | |
381 | sizeof typenames[0], compare_string_array))) { | 381 | sizeof typenames[0], compare_string_array))) { | |
382 | state->keyword = rw_type; | 382 | state->keyword = rw_type; | |
383 | state->last_u_d = true; | 383 | state->last_u_d = true; | |
384 | goto found_typename; | 384 | goto found_typename; | |
385 | } | 385 | } | |
386 | } else { /* we have a keyword */ | 386 | } else { /* we have a keyword */ | |
387 | state->keyword = p->rwcode; | 387 | state->keyword = p->rwcode; | |
388 | state->last_u_d = true; | 388 | state->last_u_d = true; | |
389 | switch (p->rwcode) { | 389 | switch (p->rwcode) { | |
390 | case rw_switch: | 390 | case rw_switch: | |
391 | return lexi_end(switch_expr); | 391 | return lexi_end(switch_expr); | |
392 | case rw_case_or_default: | 392 | case rw_case_or_default: | |
393 | return lexi_end(case_label); | 393 | return lexi_end(case_label); | |
394 | case rw_struct_or_union_or_enum: | 394 | case rw_struct_or_union_or_enum: | |
395 | case rw_type: | 395 | case rw_type: | |
396 | found_typename: | 396 | found_typename: | |
397 | if (state->p_l_follow) { | 397 | if (state->p_l_follow) { | |
398 | /* inside parens: cast, param list, offsetof or sizeof */ | 398 | /* inside parens: cast, param list, offsetof or sizeof */ | |
399 | state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; | 399 | state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask; | |
400 | } | 400 | } | |
401 | if (state->last_token == period || state->last_token == unary_op) { | 401 | if (state->last_token == period || state->last_token == unary_op) { | |
402 | state->keyword = rw_0; | 402 | state->keyword = rw_0; | |
403 | break; | 403 | break; | |
404 | } | 404 | } | |
405 | if (p != NULL && p->rwcode == rw_struct_or_union_or_enum) | 405 | if (p != NULL && p->rwcode == rw_struct_or_union_or_enum) | |
406 | return lexi_end(keyword_struct_union_enum); | 406 | return lexi_end(keyword_struct_union_enum); | |
407 | if (state->p_l_follow) | 407 | if (state->p_l_follow) | |
408 | break; | 408 | break; | |
409 | return lexi_end(decl); | 409 | return lexi_end(decl); | |
410 | 410 | |||
411 | case rw_for_or_if_or_while: | 411 | case rw_for_or_if_or_while: | |
412 | return lexi_end(keyword_for_if_while); | 412 | return lexi_end(keyword_for_if_while); | |
413 | 413 | |||
414 | case rw_do_or_else: | 414 | case rw_do_or_else: | |
415 | return lexi_end(keyword_do_else); | 415 | return lexi_end(keyword_do_else); | |
416 | 416 | |||
417 | case rw_storage_class: | 417 | case rw_storage_class: | |
418 | return lexi_end(storage_class); | 418 | return lexi_end(storage_class); | |
419 | 419 | |||
420 | case rw_typedef: | 420 | case rw_typedef: | |
421 | return lexi_end(type_def); | 421 | return lexi_end(type_def); | |
422 | 422 | |||
423 | default: /* all others are treated like any other | 423 | default: /* all others are treated like any other | |
424 | * identifier */ | 424 | * identifier */ | |
425 | return lexi_end(ident); | 425 | return lexi_end(ident); | |
426 | } /* end of switch */ | 426 | } /* end of switch */ | |
427 | } /* end of if (found_it) */ | 427 | } /* end of if (found_it) */ | |
428 | if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && | 428 | if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 && | |
429 | state->in_parameter_declaration == 0 && state->block_init == 0) { | 429 | state->in_parameter_declaration == 0 && state->block_init == 0) { | |
430 | char *tp = buf_ptr; | 430 | char *tp = buf_ptr; | |
431 | while (tp < buf_end) | 431 | while (tp < buf_end) | |
432 | if (*tp++ == ')' && (*tp == ';' || *tp == ',')) | 432 | if (*tp++ == ')' && (*tp == ';' || *tp == ',')) | |
433 | goto not_proc; | 433 | goto not_proc; | |
434 | strncpy(state->procname, token, sizeof state->procname - 1); | 434 | strncpy(state->procname, token, sizeof state->procname - 1); | |
435 | if (state->in_decl) | 435 | if (state->in_decl) | |
436 | state->in_parameter_declaration = 1; | 436 | state->in_parameter_declaration = 1; | |
437 | return lexi_end(funcname); | 437 | return lexi_end(funcname); | |
438 | not_proc:; | 438 | not_proc:; | |
439 | } | 439 | } | |
440 | /* | 440 | /* | |
441 | * The following hack attempts to guess whether or not the current | 441 | * The following hack attempts to guess whether or not the current | |
442 | * token is in fact a declaration keyword -- one that has been | 442 | * token is in fact a declaration keyword -- one that has been | |
443 | * typedefd | 443 | * typedefd | |
444 | */ | 444 | */ | |
445 | else if (!state->p_l_follow && !state->block_init && | 445 | else if (!state->p_l_follow && !state->block_init && | |
446 | !state->in_stmt && | 446 | !state->in_stmt && | |
447 | ((*buf_ptr == '*' && buf_ptr[1] != '=') || | 447 | ((*buf_ptr == '*' && buf_ptr[1] != '=') || | |
448 | isalpha((unsigned char)*buf_ptr)) && | 448 | isalpha((unsigned char)*buf_ptr)) && | |
449 | (state->last_token == semicolon || state->last_token == lbrace || | 449 | (state->last_token == semicolon || state->last_token == lbrace || | |
450 | state->last_token == rbrace)) { | 450 | state->last_token == rbrace)) { | |
451 | state->keyword = rw_type; | 451 | state->keyword = rw_type; | |
452 | state->last_u_d = true; | 452 | state->last_u_d = true; | |
453 | return lexi_end(decl); | 453 | return lexi_end(decl); | |
454 | } | 454 | } | |
455 | if (state->last_token == decl) /* if this is a declared variable, | 455 | if (state->last_token == decl) /* if this is a declared variable, | |
456 | * then following sign is unary */ | 456 | * then following sign is unary */ | |
457 | state->last_u_d = true; /* will make "int a -1" work */ | 457 | state->last_u_d = true; /* will make "int a -1" work */ | |
458 | return lexi_end(ident); /* the ident is not in the list */ | 458 | return lexi_end(ident); /* the ident is not in the list */ | |
459 | } /* end of procesing for alpanum character */ | 459 | } /* end of procesing for alpanum character */ | |
460 | 460 | |||
461 | /* Scan a non-alphanumeric token */ | 461 | /* Scan a non-alphanumeric token */ | |
462 | 462 | |||
463 | check_size_token(3); /* things like "<<=" */ | 463 | check_size_token(3); /* things like "<<=" */ | |
464 | *e_token++ = inbuf_next(); /* if it is only a one-character token, it is | 464 | *e_token++ = inbuf_next(); /* if it is only a one-character token, it is | |
465 | * moved here */ | 465 | * moved here */ | |
466 | *e_token = '\0'; | 466 | *e_token = '\0'; | |
467 | 467 | |||
468 | switch (*token) { | 468 | switch (*token) { | |
469 | case '\n': | 469 | case '\n': | |
470 | unary_delim = state->last_u_d; | 470 | unary_delim = state->last_u_d; | |
471 | state->last_nl = true; /* remember that we just had a newline */ | 471 | state->last_nl = true; /* remember that we just had a newline */ | |
472 | code = (had_eof ? end_of_file : newline); | 472 | code = (had_eof ? end_of_file : newline); | |
473 | 473 | |||
474 | /* | 474 | /* | |
475 | * if data has been exhausted, the newline is a dummy, and we should | 475 | * if data has been exhausted, the newline is a dummy, and we should | |
476 | * return code to stop | 476 | * return code to stop | |
477 | */ | 477 | */ | |
478 | break; | 478 | break; | |
479 | 479 | |||
480 | case '\'': /* start of quoted character */ | 480 | case '\'': /* start of quoted character */ | |
481 | case '"': /* start of string */ | 481 | case '"': /* start of string */ | |
482 | qchar = *token; | 482 | qchar = *token; | |
483 | do { /* copy the string */ | 483 | do { /* copy the string */ | |
484 | while (1) { /* move one character or [/<char>]<char> */ | 484 | for (;;) { /* move one character or [/<char>]<char> */ | |
485 | if (*buf_ptr == '\n') { | 485 | if (*buf_ptr == '\n') { | |
486 | diag(1, "Unterminated literal"); | 486 | diag(1, "Unterminated literal"); | |
487 | goto stop_lit; | 487 | goto stop_lit; | |
488 | } | 488 | } | |
489 | check_size_token(2); | 489 | check_size_token(2); | |
490 | *e_token = inbuf_next(); | 490 | *e_token = inbuf_next(); | |
491 | if (*e_token == '\\') { /* if escape, copy extra char */ | 491 | if (*e_token == '\\') { /* if escape, copy extra char */ | |
492 | if (*buf_ptr == '\n') /* check for escaped newline */ | 492 | if (*buf_ptr == '\n') /* check for escaped newline */ | |
493 | ++line_no; | 493 | ++line_no; | |
494 | *++e_token = inbuf_next(); | 494 | *++e_token = inbuf_next(); | |
495 | ++e_token; /* we must increment this again because we | 495 | ++e_token; /* we must increment this again because we | |
496 | * copied two chars */ | 496 | * copied two chars */ | |
497 | } else | 497 | } else | |
498 | break; /* we copied one character */ | 498 | break; /* we copied one character */ | |
499 | } /* end of while (1) */ | 499 | } /* end of while (1) */ | |
500 | } while (*e_token++ != qchar); | 500 | } while (*e_token++ != qchar); | |
501 | stop_lit: | 501 | stop_lit: | |
502 | code = ident; | 502 | code = ident; | |
503 | break; | 503 | break; | |
504 | 504 | |||
505 | case '(': | 505 | case '(': | |
506 | case '[': | 506 | case '[': | |
507 | unary_delim = true; | 507 | unary_delim = true; | |
508 | code = lparen; | 508 | code = lparen; | |
509 | break; | 509 | break; | |
510 | 510 | |||
511 | case ')': | 511 | case ')': | |
512 | case ']': | 512 | case ']': | |
513 | code = rparen; | 513 | code = rparen; | |
514 | break; | 514 | break; | |
515 | 515 | |||
516 | case '#': | 516 | case '#': | |
517 | unary_delim = state->last_u_d; | 517 | unary_delim = state->last_u_d; | |
518 | code = preprocessing; | 518 | code = preprocessing; | |
519 | break; | 519 | break; | |
520 | 520 | |||
521 | case '?': | 521 | case '?': | |
522 | unary_delim = true; | 522 | unary_delim = true; | |
523 | code = question; | 523 | code = question; | |
524 | break; | 524 | break; | |
525 | 525 | |||
526 | case ':': | 526 | case ':': | |
527 | code = colon; | 527 | code = colon; | |
528 | unary_delim = true; | 528 | unary_delim = true; | |
529 | break; | 529 | break; | |
530 | 530 | |||
531 | case ';': | 531 | case ';': | |
532 | unary_delim = true; | 532 | unary_delim = true; | |
533 | code = semicolon; | 533 | code = semicolon; | |
534 | break; | 534 | break; | |
535 | 535 | |||
536 | case '{': | 536 | case '{': | |
537 | unary_delim = true; | 537 | unary_delim = true; | |
538 | 538 | |||
539 | /* | 539 | /* | |
540 | * if (state->in_or_st) state->block_init = 1; | 540 | * if (state->in_or_st) state->block_init = 1; | |
541 | */ | 541 | */ | |
542 | /* ? code = state->block_init ? lparen : lbrace; */ | 542 | /* ? code = state->block_init ? lparen : lbrace; */ | |
543 | code = lbrace; | 543 | code = lbrace; | |
544 | break; | 544 | break; | |
545 | 545 | |||
546 | case '}': | 546 | case '}': | |
547 | unary_delim = true; | 547 | unary_delim = true; | |
548 | /* ? code = state->block_init ? rparen : rbrace; */ | 548 | /* ? code = state->block_init ? rparen : rbrace; */ | |
549 | code = rbrace; | 549 | code = rbrace; | |
550 | break; | 550 | break; | |
551 | 551 | |||
552 | case 014: /* a form feed */ | 552 | case 014: /* a form feed */ | |
553 | unary_delim = state->last_u_d; | 553 | unary_delim = state->last_u_d; | |
554 | state->last_nl = true; /* remember this so we can set 'state->col_1' | 554 | state->last_nl = true; /* remember this so we can set 'state->col_1' | |
555 | * right */ | 555 | * right */ | |
556 | code = form_feed; | 556 | code = form_feed; | |
557 | break; | 557 | break; | |
558 | 558 | |||
559 | case ',': | 559 | case ',': | |
560 | unary_delim = true; | 560 | unary_delim = true; | |
561 | code = comma; | 561 | code = comma; | |
562 | break; | 562 | break; | |
563 | 563 | |||
564 | case '.': | 564 | case '.': | |
565 | unary_delim = false; | 565 | unary_delim = false; | |
566 | code = period; | 566 | code = period; | |
567 | break; | 567 | break; | |
568 | 568 | |||
569 | case '-': | 569 | case '-': | |
570 | case '+': /* check for -, +, --, ++ */ | 570 | case '+': /* check for -, +, --, ++ */ | |
571 | code = (state->last_u_d ? unary_op : binary_op); | 571 | code = (state->last_u_d ? unary_op : binary_op); | |
572 | unary_delim = true; | 572 | unary_delim = true; | |
573 | 573 | |||
574 | if (*buf_ptr == token[0]) { | 574 | if (*buf_ptr == token[0]) { | |
575 | /* check for doubled character */ | 575 | /* check for doubled character */ | |
576 | *e_token++ = *buf_ptr++; | 576 | *e_token++ = *buf_ptr++; | |
577 | /* buffer overflow will be checked at end of loop */ | 577 | /* buffer overflow will be checked at end of loop */ | |
578 | if (state->last_token == ident || state->last_token == rparen) { | 578 | if (state->last_token == ident || state->last_token == rparen) { | |
579 | code = (state->last_u_d ? unary_op : postfix_op); | 579 | code = (state->last_u_d ? unary_op : postfix_op); | |
580 | /* check for following ++ or -- */ | 580 | /* check for following ++ or -- */ | |
581 | unary_delim = false; | 581 | unary_delim = false; | |
582 | } | 582 | } | |
583 | } else if (*buf_ptr == '=') | 583 | } else if (*buf_ptr == '=') | |
584 | /* check for operator += */ | 584 | /* check for operator += */ | |
585 | *e_token++ = *buf_ptr++; | 585 | *e_token++ = *buf_ptr++; | |
586 | else if (*buf_ptr == '>') { | 586 | else if (*buf_ptr == '>') { | |
587 | /* check for operator -> */ | 587 | /* check for operator -> */ | |
588 | *e_token++ = *buf_ptr++; | 588 | *e_token++ = *buf_ptr++; | |
589 | unary_delim = false; | 589 | unary_delim = false; | |
590 | code = unary_op; | 590 | code = unary_op; | |
591 | state->want_blank = false; | 591 | state->want_blank = false; | |
592 | } | 592 | } | |
593 | break; /* buffer overflow will be checked at end of | 593 | break; /* buffer overflow will be checked at end of | |
594 | * switch */ | 594 | * switch */ | |
595 | 595 | |||
596 | case '=': | 596 | case '=': | |
597 | if (state->in_or_st) | 597 | if (state->in_or_st) | |
598 | state->block_init = 1; | 598 | state->block_init = 1; | |
599 | if (*buf_ptr == '=') { /* == */ | 599 | if (*buf_ptr == '=') { /* == */ | |
600 | *e_token++ = '='; /* Flip =+ to += */ | 600 | *e_token++ = '='; /* Flip =+ to += */ | |
601 | buf_ptr++; | 601 | buf_ptr++; | |
602 | *e_token = 0; | 602 | *e_token = 0; | |
603 | } | 603 | } | |
604 | code = binary_op; | 604 | code = binary_op; | |
605 | unary_delim = true; | 605 | unary_delim = true; | |
606 | break; | 606 | break; | |
607 | /* can drop thru!!! */ | 607 | /* can drop thru!!! */ | |
608 | 608 | |||
609 | case '>': | 609 | case '>': | |
610 | case '<': | 610 | case '<': | |
611 | case '!': /* ops like <, <<, <=, !=, etc */ | 611 | case '!': /* ops like <, <<, <=, !=, etc */ | |
612 | if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') | 612 | if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') | |
613 | *e_token++ = inbuf_next(); | 613 | *e_token++ = inbuf_next(); | |
614 | if (*buf_ptr == '=') | 614 | if (*buf_ptr == '=') | |
615 | *e_token++ = *buf_ptr++; | 615 | *e_token++ = *buf_ptr++; | |
616 | code = (state->last_u_d ? unary_op : binary_op); | 616 | code = (state->last_u_d ? unary_op : binary_op); | |
617 | unary_delim = true; | 617 | unary_delim = true; | |
618 | break; | 618 | break; | |
619 | 619 | |||
620 | case '*': | 620 | case '*': | |
621 | unary_delim = true; | 621 | unary_delim = true; | |
622 | if (!state->last_u_d) { | 622 | if (!state->last_u_d) { | |
623 | if (*buf_ptr == '=') | 623 | if (*buf_ptr == '=') | |
624 | *e_token++ = *buf_ptr++; | 624 | *e_token++ = *buf_ptr++; | |
625 | code = binary_op; | 625 | code = binary_op; | |
626 | break; | 626 | break; | |
627 | } | 627 | } | |
628 | while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { | 628 | while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) { | |
629 | if (*buf_ptr == '*') { | 629 | if (*buf_ptr == '*') { | |
630 | check_size_token(1); | 630 | check_size_token(1); | |
631 | *e_token++ = *buf_ptr; | 631 | *e_token++ = *buf_ptr; | |
632 | } | 632 | } | |
633 | inbuf_skip(); | 633 | inbuf_skip(); | |
634 | } | 634 | } | |
635 | if (ps.in_decl) { | 635 | if (ps.in_decl) { | |
636 | char *tp = buf_ptr; | 636 | char *tp = buf_ptr; | |
637 | 637 | |||
638 | while (isalpha((unsigned char)*tp) || | 638 | while (isalpha((unsigned char)*tp) || | |
639 | isspace((unsigned char)*tp)) { | 639 | isspace((unsigned char)*tp)) { | |
640 | if (++tp >= buf_end) | 640 | if (++tp >= buf_end) | |
641 | fill_buffer(); | 641 | fill_buffer(); | |
642 | } | 642 | } | |
643 | if (*tp == '(') | 643 | if (*tp == '(') | |
644 | ps.procname[0] = ' '; | 644 | ps.procname[0] = ' '; | |
645 | } | 645 | } | |
646 | code = unary_op; | 646 | code = unary_op; | |
647 | break; | 647 | break; | |
648 | 648 | |||
649 | default: | 649 | default: | |
650 | if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { | 650 | if (token[0] == '/' && (*buf_ptr == '*' || *buf_ptr == '/')) { | |
651 | /* it is start of comment */ | 651 | /* it is start of comment */ | |
652 | *e_token++ = inbuf_next(); | 652 | *e_token++ = inbuf_next(); | |
653 | 653 | |||
654 | code = comment; | 654 | code = comment; | |
655 | unary_delim = state->last_u_d; | 655 | unary_delim = state->last_u_d; | |
656 | break; | 656 | break; | |
657 | } | 657 | } | |
658 | while (e_token[-1] == *buf_ptr || *buf_ptr == '=') { | 658 | while (e_token[-1] == *buf_ptr || *buf_ptr == '=') { | |
659 | /* | 659 | /* | |
660 | * handle ||, &&, etc, and also things as in int *****i | 660 | * handle ||, &&, etc, and also things as in int *****i | |
661 | */ | 661 | */ | |
662 | check_size_token(1); | 662 | check_size_token(1); | |
663 | *e_token++ = inbuf_next(); | 663 | *e_token++ = inbuf_next(); | |
664 | } | 664 | } | |
665 | code = (state->last_u_d ? unary_op : binary_op); | 665 | code = (state->last_u_d ? unary_op : binary_op); | |
666 | unary_delim = true; | 666 | unary_delim = true; | |
667 | 667 | |||
668 | 668 | |||
669 | } /* end of switch */ | 669 | } /* end of switch */ | |
670 | if (buf_ptr >= buf_end) /* check for input buffer empty */ | 670 | if (buf_ptr >= buf_end) /* check for input buffer empty */ | |
671 | fill_buffer(); | 671 | fill_buffer(); | |
672 | state->last_u_d = unary_delim; | 672 | state->last_u_d = unary_delim; | |
673 | check_size_token(1); | 673 | check_size_token(1); | |
674 | *e_token = '\0'; /* null terminate the token */ | 674 | *e_token = '\0'; /* null terminate the token */ | |
675 | return lexi_end(code); | 675 | return lexi_end(code); | |
676 | } | 676 | } | |
677 | 677 | |||
678 | void | 678 | void | |
679 | alloc_typenames(void) | 679 | alloc_typenames(void) | |
680 | { | 680 | { | |
681 | 681 | |||
682 | typenames = malloc(sizeof(typenames[0]) * (typename_count = 16)); | 682 | typenames = malloc(sizeof(typenames[0]) * (typename_count = 16)); | |
683 | if (typenames == NULL) | 683 | if (typenames == NULL) | |
684 | err(1, NULL); | 684 | err(1, NULL); | |
685 | } | 685 | } | |
686 | 686 | |||
687 | void | 687 | void | |
688 | add_typename(const char *key) | 688 | add_typename(const char *key) | |
689 | { | 689 | { | |
690 | int comparison; | 690 | int comparison; | |
691 | const char *copy; | 691 | const char *copy; | |
692 | 692 | |||
693 | if (typename_top + 1 >= typename_count) { | 693 | if (typename_top + 1 >= typename_count) { | |
694 | typenames = realloc((void *)typenames, | 694 | typenames = realloc((void *)typenames, | |
695 | sizeof(typenames[0]) * (typename_count *= 2)); | 695 | sizeof(typenames[0]) * (typename_count *= 2)); | |
696 | if (typenames == NULL) | 696 | if (typenames == NULL) | |
697 | err(1, NULL); | 697 | err(1, NULL); | |
698 | } | 698 | } | |
699 | if (typename_top == -1) | 699 | if (typename_top == -1) | |
700 | typenames[++typename_top] = copy = strdup(key); | 700 | typenames[++typename_top] = copy = strdup(key); | |
701 | else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { | 701 | else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) { | |
702 | /* take advantage of sorted input */ | 702 | /* take advantage of sorted input */ | |
703 | if (comparison == 0) /* remove duplicates */ | 703 | if (comparison == 0) /* remove duplicates */ | |
704 | return; | 704 | return; | |
705 | typenames[++typename_top] = copy = strdup(key); | 705 | typenames[++typename_top] = copy = strdup(key); | |
706 | } else { | 706 | } else { | |
707 | int p; | 707 | int p; | |
708 | 708 | |||
709 | for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) | 709 | for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++) | |
710 | /* find place for the new key */; | 710 | /* find place for the new key */; | |
711 | if (comparison == 0) /* remove duplicates */ | 711 | if (comparison == 0) /* remove duplicates */ | |
712 | return; | 712 | return; | |
713 | memmove(&typenames[p + 1], &typenames[p], | 713 | memmove(&typenames[p + 1], &typenames[p], | |
714 | sizeof(typenames[0]) * (++typename_top - p)); | 714 | sizeof(typenames[0]) * (++typename_top - p)); | |
715 | typenames[p] = copy = strdup(key); | 715 | typenames[p] = copy = strdup(key); | |
716 | } | 716 | } | |
717 | 717 | |||
718 | if (copy == NULL) | 718 | if (copy == NULL) | |
719 | err(1, NULL); | 719 | err(1, NULL); | |
720 | } | 720 | } |
--- src/usr.bin/indent/pr_comment.c 2021/03/13 18:11:31 1.30
+++ src/usr.bin/indent/pr_comment.c 2021/03/14 00:22:16 1.31
@@ -1,378 +1,378 @@ | @@ -1,378 +1,378 @@ | |||
1 | /* $NetBSD: pr_comment.c,v 1.30 2021/03/13 18:11:31 rillig Exp $ */ | 1 | /* $NetBSD: pr_comment.c,v 1.31 2021/03/14 00:22:16 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.30 2021/03/13 18:11:31 rillig Exp $"); | 49 | __RCSID("$NetBSD: pr_comment.c,v 1.31 2021/03/14 00:22:16 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 | * Scan, reformat and output a single comment, which is either a block comment | 82 | * Scan, reformat and output a single comment, which is either a block comment | |
83 | * starting with '/' '*' or an end-of-line comment starting with '//'. | 83 | * starting with '/' '*' or an end-of-line comment starting with '//'. | |
84 | * | 84 | * | |
85 | * Try to keep comments from going over the maximum line length. If a line is | 85 | * Try to keep comments from going over the maximum line length. If a line is | |
86 | * too long, move everything starting from the last blank to the next comment | 86 | * too long, move everything starting from the last blank to the next comment | |
87 | * line. Blanks and tabs from the beginning of the input line are removed. | 87 | * line. Blanks and tabs from the beginning of the input line are removed. | |
88 | * | 88 | * | |
89 | * ALGORITHM: | 89 | * ALGORITHM: | |
90 | * 1) Decide where the comment should be aligned, and if lines should | 90 | * 1) Decide where the comment should be aligned, and if lines should | |
91 | * be broken. | 91 | * be broken. | |
92 | * 2) If lines should not be broken and filled, just copy up to end of | 92 | * 2) If lines should not be broken and filled, just copy up to end of | |
93 | * comment. | 93 | * comment. | |
94 | * 3) If lines should be filled, then scan through the input buffer, | 94 | * 3) If lines should be filled, then scan through the input buffer, | |
95 | * copying characters to com_buf. Remember where the last blank, | 95 | * copying characters to com_buf. Remember where the last blank, | |
96 | * tab, or newline was. When line is filled, print up to last blank | 96 | * tab, or newline was. When line is filled, print up to last blank | |
97 | * and continue copying. | 97 | * and continue copying. | |
98 | */ | 98 | */ | |
99 | void | 99 | void | |
100 | process_comment(void) | 100 | process_comment(void) | |
101 | { | 101 | { | |
102 | int adj_max_line_length; /* Adjusted max_line_length for comments | 102 | int adj_max_line_length; /* Adjusted max_line_length for comments | |
103 | * that spill over the right margin */ | 103 | * that spill over the right margin */ | |
104 | char *last_bl; /* points to the last blank in the output | 104 | char *last_bl; /* points to the last blank in the output | |
105 | * buffer */ | 105 | * buffer */ | |
106 | char *t_ptr; /* used for moving string */ | 106 | char *t_ptr; /* used for moving string */ | |
107 | int break_delim = opt.comment_delimiter_on_blankline; | 107 | int break_delim = opt.comment_delimiter_on_blankline; | |
108 | int l_just_saw_decl = ps.just_saw_decl; | 108 | int l_just_saw_decl = ps.just_saw_decl; | |
109 | 109 | |||
110 | adj_max_line_length = opt.max_line_length; | 110 | adj_max_line_length = opt.max_line_length; | |
111 | ps.just_saw_decl = 0; | 111 | ps.just_saw_decl = 0; | |
112 | last_bl = NULL; /* no blanks found so far */ | 112 | last_bl = NULL; /* no blanks found so far */ | |
113 | ps.box_com = false; /* at first, assume that we are not in | 113 | ps.box_com = false; /* at first, assume that we are not in | |
114 | * a boxed comment or some other | 114 | * a boxed comment or some other | |
115 | * comment that should not be touched */ | 115 | * comment that should not be touched */ | |
116 | ++ps.out_coms; /* keep track of number of comments */ | 116 | ++ps.out_coms; /* keep track of number of comments */ | |
117 | 117 | |||
118 | /* Figure where to align and how to treat the comment */ | 118 | /* Figure where to align and how to treat the comment */ | |
119 | 119 | |||
120 | if (ps.col_1 && !opt.format_col1_comments) { /* if the comment starts in | 120 | if (ps.col_1 && !opt.format_col1_comments) { /* if the comment starts in | |
121 | * column 1, it should not be touched */ | 121 | * column 1, it should not be touched */ | |
122 | ps.box_com = true; | 122 | ps.box_com = true; | |
123 | break_delim = false; | 123 | break_delim = false; | |
124 | ps.com_col = 1; | 124 | ps.com_col = 1; | |
125 | } else { | 125 | } else { | |
126 | if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' || | 126 | if (*buf_ptr == '-' || *buf_ptr == '*' || e_token[-1] == '/' || | |
127 | (*buf_ptr == '\n' && !opt.format_block_comments)) { | 127 | (*buf_ptr == '\n' && !opt.format_block_comments)) { | |
128 | ps.box_com = true; /* A comment with a '-' or '*' immediately | 128 | ps.box_com = true; /* A comment with a '-' or '*' immediately | |
129 | * after the /+* is assumed to be a boxed | 129 | * after the /+* is assumed to be a boxed | |
130 | * comment. A comment with a newline | 130 | * comment. A comment with a newline | |
131 | * immediately after the /+* is assumed to | 131 | * immediately after the /+* is assumed to | |
132 | * be a block comment and is treated as a | 132 | * be a block comment and is treated as a | |
133 | * box comment unless format_block_comments | 133 | * box comment unless format_block_comments | |
134 | * is nonzero (the default). */ | 134 | * is nonzero (the default). */ | |
135 | break_delim = false; | 135 | break_delim = false; | |
136 | } | 136 | } | |
137 | if ( /* ps.bl_line && */ s_lab == e_lab && s_code == e_code) { | 137 | if ( /* ps.bl_line && */ s_lab == e_lab && s_code == e_code) { | |
138 | /* klg: check only if this line is blank */ | 138 | /* klg: check only if this line is blank */ | |
139 | /* | 139 | /* | |
140 | * If this (*and previous lines are*) blank, dont put comment way | 140 | * If this (*and previous lines are*) blank, dont put comment way | |
141 | * out at left | 141 | * out at left | |
142 | */ | 142 | */ | |
143 | ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.indent_size + 1; | 143 | ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.indent_size + 1; | |
144 | adj_max_line_length = opt.block_comment_max_line_length; | 144 | adj_max_line_length = opt.block_comment_max_line_length; | |
145 | if (ps.com_col <= 1) | 145 | if (ps.com_col <= 1) | |
146 | ps.com_col = 1 + !opt.format_col1_comments; | 146 | ps.com_col = 1 + !opt.format_col1_comments; | |
147 | } else { | 147 | } else { | |
148 | int target_col; | 148 | int target_col; | |
149 | break_delim = false; | 149 | break_delim = false; | |
150 | if (s_code != e_code) | 150 | if (s_code != e_code) | |
151 | target_col = 1 + indentation_after(compute_code_indent(), s_code); | 151 | target_col = 1 + indentation_after(compute_code_indent(), s_code); | |
152 | else { | 152 | else { | |
153 | target_col = 1; | 153 | target_col = 1; | |
154 | if (s_lab != e_lab) | 154 | if (s_lab != e_lab) | |
155 | target_col = 1 + indentation_after(compute_label_indent(), s_lab); | 155 | target_col = 1 + indentation_after(compute_label_indent(), s_lab); | |
156 | } | 156 | } | |
157 | ps.com_col = ps.decl_on_line || ps.ind_level == 0 | 157 | ps.com_col = ps.decl_on_line || ps.ind_level == 0 | |
158 | ? opt.decl_comment_column : opt.comment_column; | 158 | ? opt.decl_comment_column : opt.comment_column; | |
159 | if (ps.com_col <= target_col) | 159 | if (ps.com_col <= target_col) | |
160 | ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; | 160 | ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1; | |
161 | if (ps.com_col + 24 > adj_max_line_length) | 161 | if (ps.com_col + 24 > adj_max_line_length) | |
162 | /* XXX: mismatch between column and length */ | 162 | /* XXX: mismatch between column and length */ | |
163 | adj_max_line_length = ps.com_col + 24; | 163 | adj_max_line_length = ps.com_col + 24; | |
164 | } | 164 | } | |
165 | } | 165 | } | |
166 | if (ps.box_com) { | 166 | if (ps.box_com) { | |
167 | /* | 167 | /* | |
168 | * Find out how much indentation there was originally, because that | 168 | * Find out how much indentation there was originally, because that | |
169 | * much will have to be ignored by pad_output() in dump_line(). This | 169 | * much will have to be ignored by pad_output() in dump_line(). This | |
170 | * is a box comment, so nothing changes -- not even indentation. | 170 | * is a box comment, so nothing changes -- not even indentation. | |
171 | * | 171 | * | |
172 | * The comment we're about to read usually comes from in_buffer, | 172 | * The comment we're about to read usually comes from in_buffer, | |
173 | * unless it has been copied into save_com. | 173 | * unless it has been copied into save_com. | |
174 | */ | 174 | */ | |
175 | char *start; | 175 | char *start; | |
176 | 176 | |||
177 | /* | 177 | /* | |
178 | * XXX: ordered comparison between pointers from different objects | 178 | * XXX: ordered comparison between pointers from different objects | |
179 | * invokes undefined behavior (C99 6.5.8). | 179 | * invokes undefined behavior (C99 6.5.8). | |
180 | */ | 180 | */ | |
181 | start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? | 181 | start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ? | |
182 | sc_buf : in_buffer; | 182 | sc_buf : in_buffer; | |
183 | ps.n_comment_delta = -indentation_after_range(0, start, buf_ptr - 2); | 183 | ps.n_comment_delta = -indentation_after_range(0, start, buf_ptr - 2); | |
184 | } else { | 184 | } else { | |
185 | ps.n_comment_delta = 0; | 185 | ps.n_comment_delta = 0; | |
186 | while (*buf_ptr == ' ' || *buf_ptr == '\t') | 186 | while (*buf_ptr == ' ' || *buf_ptr == '\t') | |
187 | buf_ptr++; | 187 | buf_ptr++; | |
188 | } | 188 | } | |
189 | ps.comment_delta = 0; | 189 | ps.comment_delta = 0; | |
190 | *e_com++ = '/'; | 190 | *e_com++ = '/'; | |
191 | *e_com++ = e_token[-1]; | 191 | *e_com++ = e_token[-1]; | |
192 | if (*buf_ptr != ' ' && !ps.box_com) | 192 | if (*buf_ptr != ' ' && !ps.box_com) | |
193 | *e_com++ = ' '; | 193 | *e_com++ = ' '; | |
194 | 194 | |||
195 | /* | 195 | /* | |
196 | * Don't put a break delimiter if this is a one-liner that won't wrap. | 196 | * Don't put a break delimiter if this is a one-liner that won't wrap. | |
197 | */ | 197 | */ | |
198 | if (break_delim) | 198 | if (break_delim) | |
199 | for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { | 199 | for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) { | |
200 | if (t_ptr >= buf_end) | 200 | if (t_ptr >= buf_end) | |
201 | fill_buffer(); | 201 | fill_buffer(); | |
202 | if (t_ptr[0] == '*' && t_ptr[1] == '/') { | 202 | if (t_ptr[0] == '*' && t_ptr[1] == '/') { | |
203 | int right_margin = indentation_after_range(ps.com_col - 1, | 203 | int right_margin = indentation_after_range(ps.com_col - 1, | |
204 | buf_ptr, t_ptr + 2); | 204 | buf_ptr, t_ptr + 2); | |
205 | if (right_margin < adj_max_line_length) | 205 | if (right_margin < adj_max_line_length) | |
206 | break_delim = false; | 206 | break_delim = false; | |
207 | break; | 207 | break; | |
208 | } | 208 | } | |
209 | } | 209 | } | |
210 | 210 | |||
211 | if (break_delim) { | 211 | if (break_delim) { | |
212 | char *t = e_com; | 212 | char *t = e_com; | |
213 | e_com = s_com + 2; | 213 | e_com = s_com + 2; | |
214 | *e_com = 0; | 214 | *e_com = 0; | |
215 | if (opt.blanklines_before_blockcomments && ps.last_token != lbrace) | 215 | if (opt.blanklines_before_blockcomments && ps.last_token != lbrace) | |
216 | prefix_blankline_requested = 1; | 216 | prefix_blankline_requested = 1; | |
217 | dump_line(); | 217 | dump_line(); | |
218 | e_com = s_com = t; | 218 | e_com = s_com = t; | |
219 | if (!ps.box_com && opt.star_comment_cont) | 219 | if (!ps.box_com && opt.star_comment_cont) | |
220 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 220 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
221 | } | 221 | } | |
222 | 222 | |||
223 | /* Start to copy the comment */ | 223 | /* Start to copy the comment */ | |
224 | 224 | |||
225 | while (1) { /* this loop will go until the comment is | 225 | for (;;) { /* this loop will go until the comment is | |
226 | * copied */ | 226 | * copied */ | |
227 | switch (*buf_ptr) { /* this checks for various special cases */ | 227 | switch (*buf_ptr) { /* this checks for various special cases */ | |
228 | case 014: /* check for a form feed */ | 228 | case 014: /* check for a form feed */ | |
229 | check_size_comment(3, &last_bl); | 229 | check_size_comment(3, &last_bl); | |
230 | if (!ps.box_com) { /* in a text comment, break the line here */ | 230 | if (!ps.box_com) { /* in a text comment, break the line here */ | |
231 | ps.use_ff = true; | 231 | ps.use_ff = true; | |
232 | /* fix so dump_line uses a form feed */ | 232 | /* fix so dump_line uses a form feed */ | |
233 | dump_line(); | 233 | dump_line(); | |
234 | last_bl = NULL; | 234 | last_bl = NULL; | |
235 | if (!ps.box_com && opt.star_comment_cont) | 235 | if (!ps.box_com && opt.star_comment_cont) | |
236 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 236 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
237 | while (*++buf_ptr == ' ' || *buf_ptr == '\t') | 237 | while (*++buf_ptr == ' ' || *buf_ptr == '\t') | |
238 | ; | 238 | ; | |
239 | } else { | 239 | } else { | |
240 | if (++buf_ptr >= buf_end) | 240 | if (++buf_ptr >= buf_end) | |
241 | fill_buffer(); | 241 | fill_buffer(); | |
242 | *e_com++ = 014; | 242 | *e_com++ = 014; | |
243 | } | 243 | } | |
244 | break; | 244 | break; | |
245 | 245 | |||
246 | case '\n': | 246 | case '\n': | |
247 | if (e_token[-1] == '/') { | 247 | if (e_token[-1] == '/') { | |
248 | ++line_no; | 248 | ++line_no; | |
249 | goto end_of_comment; | 249 | goto end_of_comment; | |
250 | } | 250 | } | |
251 | if (had_eof) { /* check for unexpected eof */ | 251 | if (had_eof) { /* check for unexpected eof */ | |
252 | printf("Unterminated comment\n"); | 252 | printf("Unterminated comment\n"); | |
253 | dump_line(); | 253 | dump_line(); | |
254 | return; | 254 | return; | |
255 | } | 255 | } | |
256 | last_bl = NULL; | 256 | last_bl = NULL; | |
257 | check_size_comment(4, &last_bl); | 257 | check_size_comment(4, &last_bl); | |
258 | if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, | 258 | if (ps.box_com || ps.last_nl) { /* if this is a boxed comment, | |
259 | * we dont ignore the newline */ | 259 | * we dont ignore the newline */ | |
260 | if (s_com == e_com) | 260 | if (s_com == e_com) | |
261 | *e_com++ = ' '; | 261 | *e_com++ = ' '; | |
262 | if (!ps.box_com && e_com - s_com > 3) { | 262 | if (!ps.box_com && e_com - s_com > 3) { | |
263 | dump_line(); | 263 | dump_line(); | |
264 | if (opt.star_comment_cont) | 264 | if (opt.star_comment_cont) | |
265 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 265 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
266 | } | 266 | } | |
267 | dump_line(); | 267 | dump_line(); | |
268 | if (!ps.box_com && opt.star_comment_cont) | 268 | if (!ps.box_com && opt.star_comment_cont) | |
269 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 269 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
270 | } else { | 270 | } else { | |
271 | ps.last_nl = 1; | 271 | ps.last_nl = 1; | |
272 | if (e_com[-1] == ' ' || e_com[-1] == '\t') | 272 | if (e_com[-1] == ' ' || e_com[-1] == '\t') | |
273 | last_bl = e_com - 1; | 273 | last_bl = e_com - 1; | |
274 | /* | 274 | /* | |
275 | * if there was a space at the end of the last line, remember | 275 | * if there was a space at the end of the last line, remember | |
276 | * where it was | 276 | * where it was | |
277 | */ | 277 | */ | |
278 | else { /* otherwise, insert one */ | 278 | else { /* otherwise, insert one */ | |
279 | last_bl = e_com; | 279 | last_bl = e_com; | |
280 | *e_com++ = ' '; | 280 | *e_com++ = ' '; | |
281 | } | 281 | } | |
282 | } | 282 | } | |
283 | ++line_no; /* keep track of input line number */ | 283 | ++line_no; /* keep track of input line number */ | |
284 | if (!ps.box_com) { | 284 | if (!ps.box_com) { | |
285 | int nstar = 1; | 285 | int nstar = 1; | |
286 | do { /* flush any blanks and/or tabs at start of | 286 | do { /* flush any blanks and/or tabs at start of | |
287 | * next line */ | 287 | * next line */ | |
288 | if (++buf_ptr >= buf_end) | 288 | if (++buf_ptr >= buf_end) | |
289 | fill_buffer(); | 289 | fill_buffer(); | |
290 | if (*buf_ptr == '*' && --nstar >= 0) { | 290 | if (*buf_ptr == '*' && --nstar >= 0) { | |
291 | if (++buf_ptr >= buf_end) | 291 | if (++buf_ptr >= buf_end) | |
292 | fill_buffer(); | 292 | fill_buffer(); | |
293 | if (*buf_ptr == '/') | 293 | if (*buf_ptr == '/') | |
294 | goto end_of_comment; | 294 | goto end_of_comment; | |
295 | } | 295 | } | |
296 | } while (*buf_ptr == ' ' || *buf_ptr == '\t'); | 296 | } while (*buf_ptr == ' ' || *buf_ptr == '\t'); | |
297 | } else if (++buf_ptr >= buf_end) | 297 | } else if (++buf_ptr >= buf_end) | |
298 | fill_buffer(); | 298 | fill_buffer(); | |
299 | break; /* end of case for newline */ | 299 | break; /* end of case for newline */ | |
300 | 300 | |||
301 | case '*': /* must check for possibility of being at end | 301 | case '*': /* must check for possibility of being at end | |
302 | * of comment */ | 302 | * of comment */ | |
303 | if (++buf_ptr >= buf_end) /* get to next char after * */ | 303 | if (++buf_ptr >= buf_end) /* get to next char after * */ | |
304 | fill_buffer(); | 304 | fill_buffer(); | |
305 | check_size_comment(4, &last_bl); | 305 | check_size_comment(4, &last_bl); | |
306 | if (*buf_ptr == '/') { /* it is the end!!! */ | 306 | if (*buf_ptr == '/') { /* it is the end!!! */ | |
307 | end_of_comment: | 307 | end_of_comment: | |
308 | if (++buf_ptr >= buf_end) | 308 | if (++buf_ptr >= buf_end) | |
309 | fill_buffer(); | 309 | fill_buffer(); | |
310 | if (break_delim) { | 310 | if (break_delim) { | |
311 | if (e_com > s_com + 3) | 311 | if (e_com > s_com + 3) | |
312 | dump_line(); | 312 | dump_line(); | |
313 | else | 313 | else | |
314 | s_com = e_com; | 314 | s_com = e_com; | |
315 | *e_com++ = ' '; | 315 | *e_com++ = ' '; | |
316 | } | 316 | } | |
317 | if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) | 317 | if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com) | |
318 | *e_com++ = ' '; /* ensure blank before end */ | 318 | *e_com++ = ' '; /* ensure blank before end */ | |
319 | if (e_token[-1] == '/') | 319 | if (e_token[-1] == '/') | |
320 | *e_com++ = '\n', *e_com = '\0'; | 320 | *e_com++ = '\n', *e_com = '\0'; | |
321 | else | 321 | else | |
322 | *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; | 322 | *e_com++ = '*', *e_com++ = '/', *e_com = '\0'; | |
323 | ps.just_saw_decl = l_just_saw_decl; | 323 | ps.just_saw_decl = l_just_saw_decl; | |
324 | return; | 324 | return; | |
325 | } else /* handle isolated '*' */ | 325 | } else /* handle isolated '*' */ | |
326 | *e_com++ = '*'; | 326 | *e_com++ = '*'; | |
327 | break; | 327 | break; | |
328 | default: /* we have a random char */ | 328 | default: /* we have a random char */ | |
329 | ; | 329 | ; | |
330 | int now_len = indentation_after_range(ps.com_col - 1, s_com, e_com); | 330 | int now_len = indentation_after_range(ps.com_col - 1, s_com, e_com); | |
331 | do { | 331 | do { | |
332 | check_size_comment(1, &last_bl); | 332 | check_size_comment(1, &last_bl); | |
333 | *e_com = *buf_ptr++; | 333 | *e_com = *buf_ptr++; | |
334 | if (buf_ptr >= buf_end) | 334 | if (buf_ptr >= buf_end) | |
335 | fill_buffer(); | 335 | fill_buffer(); | |
336 | if (*e_com == ' ' || *e_com == '\t') | 336 | if (*e_com == ' ' || *e_com == '\t') | |
337 | last_bl = e_com; /* remember we saw a blank */ | 337 | last_bl = e_com; /* remember we saw a blank */ | |
338 | ++e_com; | 338 | ++e_com; | |
339 | now_len++; | 339 | now_len++; | |
340 | } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && | 340 | } while (!memchr("*\n\r\b\t", *buf_ptr, 6) && | |
341 | (now_len < adj_max_line_length || !last_bl)); | 341 | (now_len < adj_max_line_length || !last_bl)); | |
342 | ps.last_nl = false; | 342 | ps.last_nl = false; | |
343 | /* XXX: signed character comparison '>' does not work for UTF-8 */ | 343 | /* XXX: signed character comparison '>' does not work for UTF-8 */ | |
344 | if (now_len >= adj_max_line_length && | 344 | if (now_len >= adj_max_line_length && | |
345 | !ps.box_com && e_com[-1] > ' ') { | 345 | !ps.box_com && e_com[-1] > ' ') { | |
346 | /* | 346 | /* | |
347 | * the comment is too long, it must be broken up | 347 | * the comment is too long, it must be broken up | |
348 | */ | 348 | */ | |
349 | if (last_bl == NULL) { | 349 | if (last_bl == NULL) { | |
350 | dump_line(); | 350 | dump_line(); | |
351 | if (!ps.box_com && opt.star_comment_cont) | 351 | if (!ps.box_com && opt.star_comment_cont) | |
352 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 352 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
353 | break; | 353 | break; | |
354 | } | 354 | } | |
355 | *e_com = '\0'; | 355 | *e_com = '\0'; | |
356 | e_com = last_bl; | 356 | e_com = last_bl; | |
357 | dump_line(); | 357 | dump_line(); | |
358 | if (!ps.box_com && opt.star_comment_cont) | 358 | if (!ps.box_com && opt.star_comment_cont) | |
359 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | 359 | *e_com++ = ' ', *e_com++ = '*', *e_com++ = ' '; | |
360 | for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; | 360 | for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t'; | |
361 | t_ptr++) | 361 | t_ptr++) | |
362 | ; | 362 | ; | |
363 | last_bl = NULL; | 363 | last_bl = NULL; | |
364 | /* | 364 | /* | |
365 | * t_ptr will be somewhere between e_com (dump_line() reset) | 365 | * t_ptr will be somewhere between e_com (dump_line() reset) | |
366 | * and l_com. So it's safe to copy byte by byte from t_ptr | 366 | * and l_com. So it's safe to copy byte by byte from t_ptr | |
367 | * to e_com without any check_size_comment(). | 367 | * to e_com without any check_size_comment(). | |
368 | */ | 368 | */ | |
369 | while (*t_ptr != '\0') { | 369 | while (*t_ptr != '\0') { | |
370 | if (*t_ptr == ' ' || *t_ptr == '\t') | 370 | if (*t_ptr == ' ' || *t_ptr == '\t') | |
371 | last_bl = e_com; | 371 | last_bl = e_com; | |
372 | *e_com++ = *t_ptr++; | 372 | *e_com++ = *t_ptr++; | |
373 | } | 373 | } | |
374 | } | 374 | } | |
375 | break; | 375 | break; | |
376 | } | 376 | } | |
377 | } | 377 | } | |
378 | } | 378 | } |