Sun Mar 14 00:22:16 2021 UTC ()
indent: fix lint warnings

No functional change.


(rillig)
diff -r1.10 -r1.11 src/usr.bin/indent/Makefile
diff -r1.21 -r1.22 src/usr.bin/indent/args.c
diff -r1.58 -r1.59 src/usr.bin/indent/indent.c
diff -r1.47 -r1.48 src/usr.bin/indent/io.c
diff -r1.40 -r1.41 src/usr.bin/indent/lexi.c
diff -r1.30 -r1.31 src/usr.bin/indent/pr_comment.c

cvs diff -r1.10 -r1.11 src/usr.bin/indent/Makefile (switch to unified diff)

--- 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
4PROG= indent 4PROG= indent
5SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c 5SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c
6 6
7CPPFLAGS+= ${DEBUG:D-Ddebug} 7CPPFLAGS+= ${DEBUG:D-Ddebug}
8LINTFLAGS+= -e 8LINTFLAGS+= -e -w
 9
 10# bug in lint; see tests/usr.bin/lint/lint1/msg_168.c
 11LINTFLAGS.lexi.c+= -X 168
9 12
10.include <bsd.prog.mk> 13.include <bsd.prog.mk>

cvs diff -r1.21 -r1.22 src/usr.bin/indent/args.c (switch to unified diff)

--- 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
42static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93"; 42static 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
86static void scan_profile(FILE *); 86static 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
91const char *option_source = "?"; 91const char *option_source = "?";
92 92
93void add_typedefs_from_file(const char *str); 93void 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 */
101const struct pro { 101const 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 */
186void 186void
187set_profile(const char *profile_name) 187set_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
208static void 208static void
209scan_profile(FILE *f) 209scan_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
242static const char * 242static const char *
243eqin(const char *s1, const char *s2) 243eqin(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 */
255void 255void
256set_defaults(void) 256set_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
269void 269void
270set_option(char *arg) 270set_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);
280found: 280found:
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
343void 344void
344add_typedefs_from_file(const char *str) 345add_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}

cvs diff -r1.58 -r1.59 src/usr.bin/indent/indent.c (switch to unified diff)

--- 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
42static char sccsid[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93"; 42static 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
71struct options opt; 71struct options opt;
72struct parser_state ps; 72struct parser_state ps;
73 73
74char *labbuf; 74char *labbuf;
75char *s_lab; 75char *s_lab;
76char *e_lab; 76char *e_lab;
77char *l_lab; 77char *l_lab;
78 78
79char *codebuf; 79char *codebuf;
80char *s_code; 80char *s_code;
81char *e_code; 81char *e_code;
82char *l_code; 82char *l_code;
83 83
84char *combuf; 84char *combuf;
85char *s_com; 85char *s_com;
86char *e_com; 86char *e_com;
87char *l_com; 87char *l_com;
88 88
89char *tokenbuf; 89char *tokenbuf;
90char *s_token; 90char *s_token;
91char *e_token; 91char *e_token;
92char *l_token; 92char *l_token;
93 93
94char *in_buffer; 94char *in_buffer;
95char *in_buffer_limit; 95char *in_buffer_limit;
96char *buf_ptr; 96char *buf_ptr;
97char *buf_end; 97char *buf_end;
98 98
99char sc_buf[sc_size]; 99char sc_buf[sc_size];
100char *save_com; 100char *save_com;
101char *sc_end; 101char *sc_end;
102 102
103char *bp_save; 103char *bp_save;
104char *be_save; 104char *be_save;
105 105
106int found_err; 106int found_err;
107int n_real_blanklines; 107int n_real_blanklines;
108int prefix_blankline_requested; 108int prefix_blankline_requested;
109int postfix_blankline_requested; 109int postfix_blankline_requested;
110int break_comma; 110int break_comma;
111float case_ind; 111float case_ind;
112int code_lines; 112int code_lines;
113int had_eof; 113int had_eof;
114int line_no; 114int line_no;
115int inhibit_formatting; 115int inhibit_formatting;
116int suppress_blanklines; 116int suppress_blanklines;
117 117
118int ifdef_level; 118int ifdef_level;
119struct parser_state state_stack[5]; 119struct parser_state state_stack[5];
120struct parser_state match_state[5]; 120struct parser_state match_state[5];
121 121
122FILE *input; 122FILE *input;
123FILE *output; 123FILE *output;
124 124
125static void bakcopy(void); 125static void bakcopy(void);
126static void indent_declaration(int, int); 126static void indent_declaration(int, int);
127 127
128const char *in_name = "Standard Input"; /* will always point to name of input 128const char *in_name = "Standard Input"; /* will always point to name of input
129 * file */ 129 * file */
130const char *out_name = "Standard Output"; /* will always point to name 130const char *out_name = "Standard Output"; /* will always point to name
131 * of output file */ 131 * of output file */
132const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup 132const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup
133 * files */ 133 * files */
134char bakfile[MAXPATHLEN] = ""; 134char bakfile[MAXPATHLEN] = "";
135 135
136static void 136static void
137check_size_code(size_t desired_size) 137check_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
152static void 152static void
153check_size_label(size_t desired_size) 153check_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
169static void 169static void
170init_capsicum(void) 170init_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
186static void 186static void
187search_brace(token_type *inout_type_code, int *inout_force_nl, 187search_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
370static void 371static void
371main_init_globals(void) 372main_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
429static void 430static void
430main_parse_command_line(int argc, char **argv) 431main_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
525static void 526static void
526main_prepare_parsing(void) 527main_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
548static void 549static void
549process_end_of_file(void) 550process_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
568static void 569static void
569process_comment_in_code(token_type type_code, int *inout_force_nl) 570process_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
601static void 602static void
602process_form_feed(void) 603process_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
609static void 610static void
610process_newline(void) 611process_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
620static void 621static void
621process_lparen_or_lbracket(int dec_ind, int tabs_to_var, int sp_sw) 622process_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
670static void 671static void
671process_rparen_or_rbracket(int *inout_sp_sw, int *inout_force_nl, 672process_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
707static void 708static void
708process_unary_op(int dec_ind, int tabs_to_var) 709process_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
736static void 737static void
737process_binary_op(void) 738process_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
750static void 751static void
751process_postfix_op(void) 752process_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
758static void 759static void
759process_question(int *inout_squest) 760process_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
770static void 771static void
771process_colon(int *inout_squest, int *inout_force_nl, int *inout_scase) 772process_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
810static void 811static void
811process_semicolon(int *inout_scase, int *inout_squest, int const dec_ind, 812process_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
866static void 867static void
867process_lbrace(int *inout_force_nl, int *inout_sp_sw, token_type hd_type, 868process_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
939static void 940static void
940process_rbrace(int *inout_sp_sw, int *inout_dec_ind, const int *di_stack) 941process_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
975static void 976static void
976process_keyword_do_else(int *inout_force_nl, int *inout_last_else) 977process_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
1002static void 1003static void
1003process_decl(int *out_dec_ind, int *out_tabs_to_var) 1004process_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
1036static void 1037static void
1037process_ident(token_type type_code, int dec_ind, int tabs_to_var, 1038process_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
1066static void 1067static void
1067copy_id(void) 1068copy_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
1078static void 1079static void
1079process_string_prefix(void) 1080process_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
1092static void 1093static void
1093process_period(void) 1094process_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
1099static void 1100static void
1100process_comma(int dec_ind, int tabs_to_var, int *inout_force_nl) 1101process_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
1122static void 1123static void
1123process_preprocessing(void) 1124process_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
1271static void 1272static void
1272main_loop(void) 1273main_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
1467int 1468int
1468main(int argc, char **argv) 1469main(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 */
1484static void 1485static void
1485bakcopy(void) 1486bakcopy(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
1524static void 1525static void
1525indent_declaration(int cur_dec_ind, int tabs_to_var) 1526indent_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
1558void 1559void
1559debug_printf(const char *fmt, ...) 1560debug_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
1569void 1570void
1570debug_println(const char *fmt, ...) 1571debug_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
1581void 1582void
1582debug_vis_range(const char *prefix, const char *s, const char *e, 1583debug_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

cvs diff -r1.47 -r1.48 src/usr.bin/indent/io.c (switch to unified diff)

--- 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
42static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93"; 42static 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
64int comment_open; 64int comment_open;
65static int paren_indent; 65static int paren_indent;
66 66
67static void 67static void
68output_char(char ch) 68output_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
74static void 74static void
75output_range(const char *s, const char *e) 75output_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
81static inline void 81static inline void
82output_string(const char *s) 82output_string(const char *s)
83{ 83{
84 output_range(s, s + strlen(s)); 84 output_range(s, s + strlen(s));
85} 85}
86 86
87static int 87static int
88output_indent(int old_ind, int new_ind) 88output_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 */
115void 115void
116dump_line(void) 116dump_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
287int 287int
288compute_code_indent(void) 288compute_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
320int 320int
321compute_label_indent(void) 321compute_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 */
338void 338void
339fill_buffer(void) 339fill_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
427int 427int
428indentation_after_range(int ind, const char *start, const char *end) 428indentation_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
443int 443int
444indentation_after(int ind, const char *s) 444indentation_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
449void 449void
450diag(int level, const char *msg, ...) 450diag(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}

cvs diff -r1.40 -r1.41 src/usr.bin/indent/lexi.c (switch to unified diff)

--- 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
42static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93"; 42static 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
71struct templ { 71struct 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 */
80const struct templ specials[] = 80const 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
126const char **typenames; 126const char **typenames;
127int typename_count; 127int typename_count;
128int typename_top = -1; 128int 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 */
146static char const *table[] = { 146static 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 */
175void 175void
176init_constant_tt(void) 176init_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
190static char 190static char
191inbuf_peek(void) 191inbuf_peek(void)
192{ 192{
193 return *buf_ptr; 193 return *buf_ptr;
194} 194}
195 195
196static void 196static void
197inbuf_skip(void) 197inbuf_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
204static char 204static char
205inbuf_next(void) 205inbuf_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
212static void 212static void
213check_size_token(size_t desired_size) 213check_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
228static int 228static int
229compare_templ_array(const void *key, const void *elem) 229compare_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
234static int 234static int
235compare_string_array(const void *key, const void *elem) 235compare_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
241const char * 241const char *
242token_type_name(token_type tk) 242token_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
261static void 261static void
262print_buf(const char *name, const char *s, const char *e) 262print_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
270static token_type 270static token_type
271lexi_end(token_type code) 271lexi_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
287token_type 287token_type
288lexi(struct parser_state *state) 288lexi(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);
501stop_lit: 501stop_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
678void 678void
679alloc_typenames(void) 679alloc_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
687void 687void
688add_typename(const char *key) 688add_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}

cvs diff -r1.30 -r1.31 src/usr.bin/indent/pr_comment.c (switch to unified diff)

--- 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
42static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93"; 42static 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
62static void 62static void
63check_size_comment(size_t desired_size, char **last_bl_ptr) 63check_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 */
99void 99void
100process_comment(void) 100process_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}