Sat Jun 17 22:28:49 2023 UTC ()
indent: miscellaneous cleanups

No binary change.


(rillig)
diff -r1.66 -r1.67 src/usr.bin/indent/debug.c
diff -r1.379 -r1.380 src/usr.bin/indent/indent.c
diff -r1.227 -r1.228 src/usr.bin/indent/io.c
diff -r1.230 -r1.231 src/usr.bin/indent/lexi.c
diff -r1.77 -r1.78 src/usr.bin/indent/parse.c
diff -r1.166 -r1.167 src/usr.bin/indent/pr_comment.c

cvs diff -r1.66 -r1.67 src/usr.bin/indent/debug.c (expand / switch to unified diff)

--- src/usr.bin/indent/debug.c 2023/06/16 23:51:32 1.66
+++ src/usr.bin/indent/debug.c 2023/06/17 22:28:49 1.67
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: debug.c,v 1.66 2023/06/16 23:51:32 rillig Exp $ */ 1/* $NetBSD: debug.c,v 1.67 2023/06/17 22:28:49 rillig Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2023 The NetBSD Foundation, Inc. 4 * Copyright (c) 2023 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Roland Illig <rillig@NetBSD.org>. 8 * by Roland Illig <rillig@NetBSD.org>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__RCSID("$NetBSD: debug.c,v 1.66 2023/06/16 23:51:32 rillig Exp $"); 33__RCSID("$NetBSD: debug.c,v 1.67 2023/06/17 22:28:49 rillig Exp $");
34 34
35#include <stdarg.h> 35#include <stdarg.h>
36#include <string.h> 36#include <string.h>
37 37
38#include "indent.h" 38#include "indent.h"
39 39
40#ifdef debug 40#ifdef debug
41 41
42static struct { 42static struct {
43 // false show only the changes to the parser state 43 // false show only the changes to the parser state
44 // true show unchanged parts of the parser state as well 44 // true show unchanged parts of the parser state as well
45 bool full_parser_state; 45 bool full_parser_state;
46} config = { 46} config = {
@@ -374,19 +374,19 @@ debug_parser_state(void) @@ -374,19 +374,19 @@ debug_parser_state(void)
374 374
375 state.heading = NULL; 375 state.heading = NULL;
376 debug_blank_line(); 376 debug_blank_line();
377 377
378 state.prev_ps = ps; 378 state.prev_ps = ps;
379 state.ps_first = false; 379 state.ps_first = false;
380} 380}
381 381
382void 382void
383debug_psyms_stack(const char *situation) 383debug_psyms_stack(const char *situation)
384{ 384{
385 debug_printf("parse stack %s:", situation); 385 debug_printf("parse stack %s:", situation);
386 const struct psym_stack *psyms = &ps.psyms; 386 const struct psym_stack *psyms = &ps.psyms;
387 for (size_t i = 0; i < psyms->len; ++i) 387 for (size_t i = 0; i < psyms->len; i++)
388 debug_printf(" %d %s", 388 debug_printf(" %d %s",
389 psyms->ind_level[i], psym_name[psyms->sym[i]]); 389 psyms->ind_level[i], psym_name[psyms->sym[i]]);
390 debug_println(""); 390 debug_println("");
391} 391}
392#endif 392#endif

cvs diff -r1.379 -r1.380 src/usr.bin/indent/indent.c (expand / switch to unified diff)

--- src/usr.bin/indent/indent.c 2023/06/16 23:51:32 1.379
+++ src/usr.bin/indent/indent.c 2023/06/17 22:28:49 1.380
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: indent.c,v 1.379 2023/06/16 23:51:32 rillig Exp $ */ 1/* $NetBSD: indent.c,v 1.380 2023/06/17 22:28:49 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
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE. 37 * SUCH DAMAGE.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: indent.c,v 1.379 2023/06/16 23:51:32 rillig Exp $"); 41__RCSID("$NetBSD: indent.c,v 1.380 2023/06/17 22:28:49 rillig Exp $");
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <err.h> 44#include <err.h>
45#include <stdarg.h> 45#include <stdarg.h>
46#include <stdio.h> 46#include <stdio.h>
47#include <stdlib.h> 47#include <stdlib.h>
48#include <string.h> 48#include <string.h>
49 49
50#include "indent.h" 50#include "indent.h"
51 51
52struct options opt = { 52struct options opt = {
53 .brace_same_line = true, 53 .brace_same_line = true,
54 .comment_delimiter_on_blank_line = true, 54 .comment_delimiter_on_blank_line = true,
@@ -167,51 +167,51 @@ diag(int level, const char *msg, ...) @@ -167,51 +167,51 @@ diag(int level, const char *msg, ...)
167/* 167/*
168 * Compute the indentation from starting at 'ind' and adding the text starting 168 * Compute the indentation from starting at 'ind' and adding the text starting
169 * at 's'. 169 * at 's'.
170 */ 170 */
171int 171int
172ind_add(int ind, const char *s, size_t len) 172ind_add(int ind, const char *s, size_t len)
173{ 173{
174 for (const char *p = s; len > 0; p++, len--) { 174 for (const char *p = s; len > 0; p++, len--) {
175 if (*p == '\n') 175 if (*p == '\n')
176 ind = 0; 176 ind = 0;
177 else if (*p == '\t') 177 else if (*p == '\t')
178 ind = next_tab(ind); 178 ind = next_tab(ind);
179 else if (*p == '\b') 179 else if (*p == '\b')
180 --ind; 180 ind--;
181 else 181 else
182 ++ind; 182 ind++;
183 } 183 }
184 return ind; 184 return ind;
185} 185}
186 186
187static void 187static void
188init_globals(void) 188init_globals(void)
189{ 189{
190 ps_push(psym_stmt, false); /* as a stop symbol */ 190 ps_push(psym_stmt, false); /* as a stop symbol */
191 ps.prev_lsym = lsym_semicolon; 191 ps.prev_lsym = lsym_semicolon;
192 ps.lbrace_kind = psym_lbrace_block; 192 ps.lbrace_kind = psym_lbrace_block;
193 193
194 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX"); 194 const char *suffix = getenv("SIMPLE_BACKUP_SUFFIX");
195 if (suffix != NULL) 195 if (suffix != NULL)
196 backup_suffix = suffix; 196 backup_suffix = suffix;
197} 197}
198 198
199static void 199static void
200load_profiles(int argc, char **argv) 200load_profiles(int argc, char **argv)
201{ 201{
202 const char *profile_name = NULL; 202 const char *profile_name = NULL;
203 203
204 for (int i = 1; i < argc; ++i) { 204 for (int i = 1; i < argc; i++) {
205 const char *arg = argv[i]; 205 const char *arg = argv[i];
206 206
207 if (strcmp(arg, "-npro") == 0) 207 if (strcmp(arg, "-npro") == 0)
208 return; 208 return;
209 if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0') 209 if (arg[0] == '-' && arg[1] == 'P' && arg[2] != '\0')
210 profile_name = arg + 2; 210 profile_name = arg + 2;
211 } 211 }
212 212
213 load_profile_files(profile_name); 213 load_profile_files(profile_name);
214} 214}
215 215
216/* 216/*
217 * Copy the input file to the backup file, then make the backup file the input 217 * Copy the input file to the backup file, then make the backup file the input
@@ -245,27 +245,27 @@ copy_to_bak_file(void) @@ -245,27 +245,27 @@ copy_to_bak_file(void)
245 if (input == NULL) 245 if (input == NULL)
246 err(1, "%s", backup_name); 246 err(1, "%s", backup_name);
247 /* now the original input file will be the output */ 247 /* now the original input file will be the output */
248 output = fopen(in_name, "w"); 248 output = fopen(in_name, "w");
249 if (output == NULL) { 249 if (output == NULL) {
250 remove(backup_name); 250 remove(backup_name);
251 err(1, "%s", in_name); 251 err(1, "%s", in_name);
252 } 252 }
253} 253}
254 254
255static void 255static void
256parse_command_line(int argc, char **argv) 256parse_command_line(int argc, char **argv)
257{ 257{
258 for (int i = 1; i < argc; ++i) { 258 for (int i = 1; i < argc; i++) {
259 const char *arg = argv[i]; 259 const char *arg = argv[i];
260 260
261 if (arg[0] == '-') { 261 if (arg[0] == '-') {
262 set_option(arg, "Command line"); 262 set_option(arg, "Command line");
263 263
264 } else if (input == NULL) { 264 } else if (input == NULL) {
265 in_name = arg; 265 in_name = arg;
266 if ((input = fopen(in_name, "r")) == NULL) 266 if ((input = fopen(in_name, "r")) == NULL)
267 err(1, "%s", in_name); 267 err(1, "%s", in_name);
268 268
269 } else if (output == NULL) { 269 } else if (output == NULL) {
270 if (strcmp(arg, in_name) == 0) 270 if (strcmp(arg, in_name) == 0)
271 errx(1, "input and output files " 271 errx(1, "input and output files "
@@ -556,27 +556,27 @@ process_newline(void) @@ -556,27 +556,27 @@ process_newline(void)
556 && lab.len == 0 /* for preprocessing lines */ 556 && lab.len == 0 /* for preprocessing lines */
557 && com.len == 0) 557 && com.len == 0)
558 goto stay_in_line; 558 goto stay_in_line;
559 if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr 559 if (ps.psyms.sym[ps.psyms.len - 1] == psym_switch_expr
560 && opt.brace_same_line 560 && opt.brace_same_line
561 && com.len == 0) { 561 && com.len == 0) {
562 ps.want_newline = true; 562 ps.want_newline = true;
563 goto stay_in_line; 563 goto stay_in_line;
564 } 564 }
565 565
566 output_line(); 566 output_line();
567 567
568stay_in_line: 568stay_in_line:
569 ++line_no; 569 line_no++;
570} 570}
571 571
572static bool 572static bool
573want_blank_before_lparen(void) 573want_blank_before_lparen(void)
574{ 574{
575 if (opt.proc_calls_space) 575 if (opt.proc_calls_space)
576 return true; 576 return true;
577 if (ps.prev_lsym == lsym_sizeof) 577 if (ps.prev_lsym == lsym_sizeof)
578 return opt.blank_after_sizeof; 578 return opt.blank_after_sizeof;
579 if (ps.prev_lsym == lsym_rparen 579 if (ps.prev_lsym == lsym_rparen
580 || ps.prev_lsym == lsym_rbracket 580 || ps.prev_lsym == lsym_rbracket
581 || ps.prev_lsym == lsym_postfix_op 581 || ps.prev_lsym == lsym_postfix_op
582 || ps.prev_lsym == lsym_offsetof 582 || ps.prev_lsym == lsym_offsetof

cvs diff -r1.227 -r1.228 src/usr.bin/indent/io.c (expand / switch to unified diff)

--- src/usr.bin/indent/io.c 2023/06/16 11:48:32 1.227
+++ src/usr.bin/indent/io.c 2023/06/17 22:28:49 1.228
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: io.c,v 1.227 2023/06/16 11:48:32 rillig Exp $ */ 1/* $NetBSD: io.c,v 1.228 2023/06/17 22:28:49 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
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE. 37 * SUCH DAMAGE.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: io.c,v 1.227 2023/06/16 11:48:32 rillig Exp $"); 41__RCSID("$NetBSD: io.c,v 1.228 2023/06/17 22:28:49 rillig Exp $");
42 42
43#include <stdio.h> 43#include <stdio.h>
44 44
45#include "indent.h" 45#include "indent.h"
46 46
47struct buffer inp; 47struct buffer inp;
48const char *inp_p; 48const char *inp_p;
49 49
50struct output_state out; 50struct output_state out;
51enum indent_enabled indent_enabled; 51enum indent_enabled indent_enabled;
52static int out_ind; /* width of the line that is being written */ 52static int out_ind; /* width of the line that is being written */
53static unsigned newlines = 2; /* the total of written and buffered newlines; 53static unsigned newlines = 2; /* the total of written and buffered newlines;
54 * 0 in the middle of a line, 1 after a single 54 * 0 in the middle of a line, 1 after a single
@@ -321,26 +321,30 @@ output_comment(void) @@ -321,26 +321,30 @@ output_comment(void)
321 } 321 }
322 322
323 if (out_ind > target_ind) 323 if (out_ind > target_ind)
324 add_buffered_newline(); 324 add_buffered_newline();
325 325
326 while (com.s + com.len > p && ch_isspace(com.s[com.len - 1])) 326 while (com.s + com.len > p && ch_isspace(com.s[com.len - 1]))
327 com.len--; 327 com.len--;
328 buf_terminate(&com); 328 buf_terminate(&com);
329 329
330 write_indent(target_ind); 330 write_indent(target_ind);
331 write_range(p, com.len - (size_t)(p - com.s)); 331 write_range(p, com.len - (size_t)(p - com.s));
332} 332}
333 333
 334/*
 335 * Write a line of formatted source to the output file. The line consists of
 336 * the label, the code and the comment.
 337 */
334static void 338static void
335output_indented_line(void) 339output_indented_line(void)
336{ 340{
337 if (lab.len == 0 && code.len == 0 && com.len == 0) 341 if (lab.len == 0 && code.len == 0 && com.len == 0)
338 out.line_kind = lk_blank; 342 out.line_kind = lk_blank;
339 343
340 if (want_blank_line() && newlines < 2 344 if (want_blank_line() && newlines < 2
341 && out.line_kind != lk_blank) 345 && out.line_kind != lk_blank)
342 add_buffered_newline(); 346 add_buffered_newline();
343 347
344 /* This kludge aligns function definitions correctly. */ 348 /* This kludge aligns function definitions correctly. */
345 if (ps.ind_level == 0) 349 if (ps.ind_level == 0)
346 ps.line_is_stmt_cont = false; 350 ps.line_is_stmt_cont = false;
@@ -372,67 +376,69 @@ output_indented_line(void) @@ -372,67 +376,69 @@ output_indented_line(void)
372static bool 376static bool
373is_stmt_cont(void) 377is_stmt_cont(void)
374{ 378{
375 if (ps.psyms.len >= 2 379 if (ps.psyms.len >= 2
376 && ps.psyms.sym[ps.psyms.len - 2] == psym_lbrace_enum 380 && ps.psyms.sym[ps.psyms.len - 2] == psym_lbrace_enum
377 && ps.prev_lsym == lsym_comma 381 && ps.prev_lsym == lsym_comma
378 && ps.paren.len == 0) 382 && ps.paren.len == 0)
379 return false; 383 return false;
380 return ps.in_stmt_or_decl 384 return ps.in_stmt_or_decl
381 && (!ps.in_decl || ps.in_init) 385 && (!ps.in_decl || ps.in_init)
382 && ps.init_level == 0; 386 && ps.init_level == 0;
383} 387}
384 388
385/* 389static void
386 * Write a line of formatted source to the output file. The line consists of 390prepare_next_line(void)
387 * the label, the code and the comment. 
388 */ 
389void 
390output_line(void) 
391{ 391{
392 debug_blank_line(); 
393 debug_printf("%s", __func__); 
394 debug_buffers(); 
395 
396 if (indent_enabled == indent_on) 
397 output_indented_line(); 
398 else if (indent_enabled == indent_last_off_line) { 
399 indent_enabled = indent_on; 
400 write_range(out.indent_off_text.s, out.indent_off_text.len); 
401 buf_clear(&out.indent_off_text); 
402 } 
403 
404 buf_clear(&lab); 
405 buf_clear(&code); 
406 buf_clear(&com); 
407 
408 ps.line_has_decl = ps.in_decl; 392 ps.line_has_decl = ps.in_decl;
409 ps.line_has_func_def = false; 393 ps.line_has_func_def = false;
410 ps.line_is_stmt_cont = is_stmt_cont(); 394 ps.line_is_stmt_cont = is_stmt_cont();
411 ps.decl_indent_done = false; 395 ps.decl_indent_done = false;
412 if (ps.extra_expr_indent == eei_last) 396 if (ps.extra_expr_indent == eei_last)
413 ps.extra_expr_indent = eei_no; 397 ps.extra_expr_indent = eei_no;
414 if (!(ps.psyms.sym[ps.psyms.len - 1] == psym_if_expr_stmt_else 398 if (!(ps.psyms.sym[ps.psyms.len - 1] == psym_if_expr_stmt_else
415 && ps.paren.len > 0)) 399 && ps.paren.len > 0))
416 ps.ind_level = ps.ind_level_follow; 400 ps.ind_level = ps.ind_level_follow;
417 ps.ind_paren_level = (int)ps.paren.len; 401 ps.ind_paren_level = (int)ps.paren.len;
418 ps.want_blank = false; 402 ps.want_blank = false;
419 403
420 if (ps.paren.len > 0) { 404 if (ps.paren.len > 0) {
421 /* TODO: explain what negative indentation means */ 405 /* TODO: explain what negative indentation means */
422 paren_indent = -1 - ps.paren.item[ps.paren.len - 1].indent; 406 paren_indent = -1 - ps.paren.item[ps.paren.len - 1].indent;
423 debug_println("paren_indent is now %d", paren_indent); 407 debug_println("paren_indent is now %d", paren_indent);
424 } 408 }
425 409
426 out.line_kind = lk_other; 410 out.line_kind = lk_other;
427} 411}
428 412
429void 413void
 414output_line(void)
 415{
 416 debug_blank_line();
 417 debug_printf("%s", __func__);
 418 debug_buffers();
 419
 420 if (indent_enabled == indent_on)
 421 output_indented_line();
 422 else if (indent_enabled == indent_last_off_line) {
 423 indent_enabled = indent_on;
 424 write_range(out.indent_off_text.s, out.indent_off_text.len);
 425 buf_clear(&out.indent_off_text);
 426 }
 427
 428 buf_clear(&lab);
 429 buf_clear(&code);
 430 buf_clear(&com);
 431
 432 prepare_next_line();
 433}
 434
 435void
430finish_output(void) 436finish_output(void)
431{ 437{
432 output_line(); 438 output_line();
433 if (indent_enabled != indent_on) { 439 if (indent_enabled != indent_on) {
434 indent_enabled = indent_last_off_line; 440 indent_enabled = indent_last_off_line;
435 output_line(); 441 output_line();
436 } 442 }
437 fflush(output); 443 fflush(output);
438} 444}

cvs diff -r1.230 -r1.231 src/usr.bin/indent/lexi.c (expand / switch to unified diff)

--- src/usr.bin/indent/lexi.c 2023/06/16 23:51:32 1.230
+++ src/usr.bin/indent/lexi.c 2023/06/17 22:28:49 1.231
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lexi.c,v 1.230 2023/06/16 23:51:32 rillig Exp $ */ 1/* $NetBSD: lexi.c,v 1.231 2023/06/17 22:28:49 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
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE. 37 * SUCH DAMAGE.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: lexi.c,v 1.230 2023/06/16 23:51:32 rillig Exp $"); 41__RCSID("$NetBSD: lexi.c,v 1.231 2023/06/17 22:28:49 rillig Exp $");
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "indent.h" 46#include "indent.h"
47 47
48/* must be sorted alphabetically, is used in binary search */ 48/* must be sorted alphabetically, is used in binary search */
49static const struct keyword { 49static const struct keyword {
50 const char name[12]; 50 const char name[12];
51 lexer_symbol lsym; 51 lexer_symbol lsym;
52} keywords[] = { 52} keywords[] = {
53 {"_Bool", lsym_type}, 53 {"_Bool", lsym_type},
54 {"_Complex", lsym_type}, 54 {"_Complex", lsym_type},
@@ -176,43 +176,41 @@ is_identifier_part(char ch) @@ -176,43 +176,41 @@ is_identifier_part(char ch)
176 return ch_isalnum(ch) || ch == '_' || ch == '$'; 176 return ch_isalnum(ch) || ch == '_' || ch == '$';
177} 177}
178 178
179static void 179static void
180token_add_char(char ch) 180token_add_char(char ch)
181{ 181{
182 buf_add_char(&token, ch); 182 buf_add_char(&token, ch);
183} 183}
184 184
185static void 185static void
186lex_number(void) 186lex_number(void)
187{ 187{
188 for (unsigned char s = 'A'; s != 'f' && s != 'i' && s != 'u';) { 188 for (unsigned char s = 'A'; s != 'f' && s != 'i' && s != 'u';) {
189 unsigned char ch = (unsigned char)inp_p[0]; 189 unsigned char ch = (unsigned char)*inp_p;
190 if (ch == '\\' && inp_p[1] == '\n') { 190 if (ch == '\\' && inp_p[1] == '\n') {
191 inp_p++; 191 inp_p++;
192 inp_skip(); 192 inp_skip();
193 line_no++; 193 line_no++;
194 continue; 194 continue;
195 } 195 }
196 if (ch >= array_length(lex_number_row) 196 if (ch >= array_length(lex_number_row)
197 || lex_number_row[ch] == 0) 197 || lex_number_row[ch] == 0)
198 break; 198 break;
199 199
200 unsigned char row = lex_number_row[ch]; 200 unsigned char row = lex_number_row[ch];
201 if (lex_number_state[row][s - 'A'] == ' ') { 201 if (lex_number_state[row][s - 'A'] == ' ') {
202 /*- 202 // lex_number_state[0][s - 'A'] now indicates the type:
203 * lex_number_state[0][s - 'A'] now indicates the type: 203 // f = floating, i = integer, u = unknown
204 * f = floating, i = integer, u = unknown 
205 */ 
206 return; 204 return;
207 } 205 }
208 206
209 s = lex_number_state[row][s - 'A']; 207 s = lex_number_state[row][s - 'A'];
210 token_add_char(inp_next()); 208 token_add_char(inp_next());
211 } 209 }
212} 210}
213 211
214static void 212static void
215lex_word(void) 213lex_word(void)
216{ 214{
217 for (;;) { 215 for (;;) {
218 if (is_identifier_part(inp_p[0])) 216 if (is_identifier_part(inp_p[0]))
@@ -220,38 +218,38 @@ lex_word(void) @@ -220,38 +218,38 @@ lex_word(void)
220 else if (inp_p[0] == '\\' && inp_p[1] == '\n') { 218 else if (inp_p[0] == '\\' && inp_p[1] == '\n') {
221 inp_p++; 219 inp_p++;
222 inp_skip(); 220 inp_skip();
223 line_no++; 221 line_no++;
224 } else 222 } else
225 return; 223 return;
226 } 224 }
227} 225}
228 226
229static void 227static void
230lex_char_or_string(void) 228lex_char_or_string(void)
231{ 229{
232 for (char delim = token.s[token.len - 1];;) { 230 for (char delim = token.s[token.len - 1];;) {
233 if (inp_p[0] == '\n') { 231 if (*inp_p == '\n') {
234 diag(1, "Unterminated literal"); 232 diag(1, "Unterminated literal");
235 return; 233 return;
236 } 234 }
237 235
238 token_add_char(*inp_p++); 236 token_add_char(*inp_p++);
239 if (token.s[token.len - 1] == delim) 237 if (token.s[token.len - 1] == delim)
240 return; 238 return;
241 239
242 if (token.s[token.len - 1] == '\\') { 240 if (token.s[token.len - 1] == '\\') {
243 if (inp_p[0] == '\n') 241 if (*inp_p == '\n')
244 ++line_no; 242 line_no++;
245 token_add_char(inp_next()); 243 token_add_char(inp_next());
246 } 244 }
247 } 245 }
248} 246}
249 247
250/* Guess whether the current token is a declared type. */ 248/* Guess whether the current token is a declared type. */
251static bool 249static bool
252probably_typename(void) 250probably_typename(void)
253{ 251{
254 if (ps.prev_lsym == lsym_modifier) 252 if (ps.prev_lsym == lsym_modifier)
255 return true; 253 return true;
256 if (ps.in_init) 254 if (ps.in_init)
257 return false; 255 return false;
@@ -315,28 +313,28 @@ register_typename(const char *name) @@ -315,28 +313,28 @@ register_typename(const char *name)
315 pos = -1 - pos; 313 pos = -1 - pos;
316 memmove(typenames.items + pos + 1, typenames.items + pos, 314 memmove(typenames.items + pos + 1, typenames.items + pos,
317 sizeof(typenames.items[0]) * (typenames.len++ - (unsigned)pos)); 315 sizeof(typenames.items[0]) * (typenames.len++ - (unsigned)pos));
318 typenames.items[pos] = nonnull(strdup(name)); 316 typenames.items[pos] = nonnull(strdup(name));
319} 317}
320 318
321static int 319static int
322cmp_keyword_by_name(const void *key, const void *elem) 320cmp_keyword_by_name(const void *key, const void *elem)
323{ 321{
324 return strcmp(key, ((const struct keyword *)elem)->name); 322 return strcmp(key, ((const struct keyword *)elem)->name);
325} 323}
326 324
327/* 325/*
328 * Looking at something like 'function_name(...)' in a line, guess whether 326 * Looking at the '(', guess whether this starts a function definition or a
329 * this starts a function definition or a declaration. 327 * function declaration.
330 */ 328 */
331static bool 329static bool
332probably_function_definition(void) 330probably_function_definition(void)
333{ 331{
334 int paren_level = 0; 332 int paren_level = 0;
335 for (const char *p = inp_p; *p != '\n'; p++) { 333 for (const char *p = inp_p; *p != '\n'; p++) {
336 if (*p == '(') 334 if (*p == '(')
337 paren_level++; 335 paren_level++;
338 if (*p == ')' && --paren_level == 0) { 336 if (*p == ')' && --paren_level == 0) {
339 p++; 337 p++;
340 338
341 while (*p != '\n' 339 while (*p != '\n'
342 && (ch_isspace(*p) || is_identifier_part(*p))) 340 && (ch_isspace(*p) || is_identifier_part(*p)))
@@ -349,65 +347,67 @@ probably_function_definition(void) @@ -349,65 +347,67 @@ probably_function_definition(void)
349 if (*p == ',') /* double abs(), pi; */ 347 if (*p == ',') /* double abs(), pi; */
350 return false; 348 return false;
351 if (*p == '(') /* func(...) __attribute__((...)) */ 349 if (*p == '(') /* func(...) __attribute__((...)) */
352 paren_level++; /* func(...) __printflike(...) 350 paren_level++; /* func(...) __printflike(...)
353 */ 351 */
354 else 352 else
355 break; /* func(...) { ... */ 353 break; /* func(...) { ... */
356 } 354 }
357 355
358 if (paren_level == 1 && p[0] == '*' && p[1] == ',') 356 if (paren_level == 1 && p[0] == '*' && p[1] == ',')
359 return false; 357 return false;
360 } 358 }
361 359
362 /* To further reduce the cases where indent wrongly treats an 360 /*
 361 * To further reduce the cases where indent wrongly treats an
363 * incomplete function declaration as a function definition, thus 362 * incomplete function declaration as a function definition, thus
364 * adding a newline before the function name, it may be worth looking 363 * adding a newline before the function name, it may be worth looking
365 * for parameter names, as these are often omitted in function 364 * for parameter names, as these are often omitted in function
366 * declarations and only included in function definitions. Or just 365 * declarations and only included in function definitions. Or just
367 * increase the lookahead to more than just the current line of input, 366 * increase the lookahead to more than just the current line of input,
368 * until the next '{'. */ 367 * until the next '{'.
 368 */
369 return true; 369 return true;
370} 370}
371 371
372static lexer_symbol 372static lexer_symbol
373lexi_alnum(void) 373lexi_alnum(void)
374{ 374{
375 if (ch_isdigit(inp_p[0]) || 375 if (ch_isdigit(inp_p[0]) ||
376 (inp_p[0] == '.' && ch_isdigit(inp_p[1]))) { 376 (inp_p[0] == '.' && ch_isdigit(inp_p[1]))) {
377 lex_number(); 377 lex_number();
378 } else if (is_identifier_start(inp_p[0])) { 378 } else if (is_identifier_start(inp_p[0])) {
379 lex_word(); 379 lex_word();
380 380
381 if (token.len == 1 && token.s[0] == 'L' && 381 if (token.len == 1 && token.s[0] == 'L' &&
382 (inp_p[0] == '"' || inp_p[0] == '\'')) { 382 (inp_p[0] == '"' || inp_p[0] == '\'')) {
383 token_add_char(*inp_p++); 383 token_add_char(*inp_p++);
384 lex_char_or_string(); 384 lex_char_or_string();
385 ps.next_unary = false; 385 ps.next_unary = false;
386 return lsym_word; 386 return lsym_word;
387 } 387 }
388 } else 388 } else
389 return lsym_eof; /* just as a placeholder */ 389 return lsym_eof; /* just as a placeholder */
390 390
391 while (ch_isblank(inp_p[0])) 391 while (ch_isblank(*inp_p))
392 inp_p++; 392 inp_p++;
393 393
394 ps.next_unary = ps.prev_lsym == lsym_tag 394 ps.next_unary = ps.prev_lsym == lsym_tag
395 || ps.prev_lsym == lsym_typedef; 395 || ps.prev_lsym == lsym_typedef;
396 396
397 if (ps.prev_lsym == lsym_tag && ps.paren.len == 0) 397 if (ps.prev_lsym == lsym_tag && ps.paren.len == 0)
398 return lsym_type; 398 return lsym_type;
399 399
400 token_add_char('\0'); 400 token_add_char('\0'); // Terminate in non-debug mode as well.
401 token.len--; 401 token.len--;
402 const struct keyword *kw = bsearch(token.s, keywords, 402 const struct keyword *kw = bsearch(token.s, keywords,
403 array_length(keywords), sizeof(keywords[0]), cmp_keyword_by_name); 403 array_length(keywords), sizeof(keywords[0]), cmp_keyword_by_name);
404 lexer_symbol lsym = lsym_word; 404 lexer_symbol lsym = lsym_word;
405 if (kw != NULL) { 405 if (kw != NULL) {
406 if (kw->lsym == lsym_type) 406 if (kw->lsym == lsym_type)
407 lsym = lsym_type; 407 lsym = lsym_type;
408 ps.next_unary = true; 408 ps.next_unary = true;
409 if (kw->lsym == lsym_tag || kw->lsym == lsym_type) 409 if (kw->lsym == lsym_tag || kw->lsym == lsym_type)
410 goto found_typename; 410 goto found_typename;
411 return kw->lsym; 411 return kw->lsym;
412 } 412 }
413 413
@@ -422,27 +422,27 @@ found_typename: @@ -422,27 +422,27 @@ found_typename:
422 ps.paren.item + ps.paren.len - 1; 422 ps.paren.item + ps.paren.len - 1;
423 if (paren_level->cast == cast_unknown) 423 if (paren_level->cast == cast_unknown)
424 paren_level->cast = cast_maybe; 424 paren_level->cast = cast_maybe;
425 } 425 }
426 if (ps.prev_lsym != lsym_period 426 if (ps.prev_lsym != lsym_period
427 && ps.prev_lsym != lsym_unary_op) { 427 && ps.prev_lsym != lsym_unary_op) {
428 if (kw != NULL && kw->lsym == lsym_tag) 428 if (kw != NULL && kw->lsym == lsym_tag)
429 return lsym_tag; 429 return lsym_tag;
430 if (ps.paren.len == 0) 430 if (ps.paren.len == 0)
431 return lsym_type; 431 return lsym_type;
432 } 432 }
433 } 433 }
434 434
435 if (inp_p[0] == '(' && ps.psyms.len <= 2 && ps.ind_level == 0 && 435 if (*inp_p == '(' && ps.psyms.len < 3 && ps.ind_level == 0 &&
436 !ps.in_func_def_params && !ps.in_init) { 436 !ps.in_func_def_params && !ps.in_init) {
437 437
438 if (ps.paren.len == 0 && probably_function_definition()) { 438 if (ps.paren.len == 0 && probably_function_definition()) {
439 ps.line_has_func_def = true; 439 ps.line_has_func_def = true;
440 if (ps.in_decl) 440 if (ps.in_decl)
441 ps.in_func_def_params = true; 441 ps.in_func_def_params = true;
442 return lsym_funcname; 442 return lsym_funcname;
443 } 443 }
444 444
445 } else if (ps.paren.len == 0 && probably_typename()) { 445 } else if (ps.paren.len == 0 && probably_typename()) {
446 ps.next_unary = true; 446 ps.next_unary = true;
447 return lsym_type; 447 return lsym_type;
448 } 448 }
@@ -457,44 +457,44 @@ is_asterisk_pointer(void) @@ -457,44 +457,44 @@ is_asterisk_pointer(void)
457 return true; 457 return true;
458 if (ps.next_unary || ps.in_func_def_params) 458 if (ps.next_unary || ps.in_func_def_params)
459 return true; 459 return true;
460 if (ps.prev_lsym == lsym_word || 460 if (ps.prev_lsym == lsym_word ||
461 ps.prev_lsym == lsym_rparen || 461 ps.prev_lsym == lsym_rparen ||
462 ps.prev_lsym == lsym_rbracket) 462 ps.prev_lsym == lsym_rbracket)
463 return false; 463 return false;
464 return ps.in_decl && ps.paren.len > 0; 464 return ps.in_decl && ps.paren.len > 0;
465} 465}
466 466
467static bool 467static bool
468probably_in_function_definition(void) 468probably_in_function_definition(void)
469{ 469{
470 for (const char *tp = inp_p; *tp != '\n';) { 470 for (const char *p = inp_p; *p != '\n';) {
471 if (ch_isspace(*tp)) 471 if (ch_isspace(*p))
472 tp++; 472 p++;
473 else if (is_identifier_start(*tp)) { 473 else if (is_identifier_start(*p)) {
474 tp++; 474 p++;
475 while (is_identifier_part(*tp)) 475 while (is_identifier_part(*p))
476 tp++; 476 p++;
477 } else 477 } else
478 return *tp == '('; 478 return *p == '(';
479 } 479 }
480 return false; 480 return false;
481} 481}
482 482
483static void 483static void
484lex_asterisk_pointer(void) 484lex_asterisk_pointer(void)
485{ 485{
486 while (inp_p[0] == '*' || ch_isspace(inp_p[0])) { 486 while (*inp_p == '*' || ch_isspace(*inp_p)) {
487 if (inp_p[0] == '*') 487 if (*inp_p == '*')
488 token_add_char('*'); 488 token_add_char('*');
489 inp_skip(); 489 inp_skip();
490 } 490 }
491 491
492 if (ps.in_decl && probably_in_function_definition()) 492 if (ps.in_decl && probably_in_function_definition())
493 ps.line_has_func_def = true; 493 ps.line_has_func_def = true;
494} 494}
495 495
496static bool 496static bool
497skip(const char **pp, const char *s) 497skip(const char **pp, const char *s)
498{ 498{
499 size_t len = strlen(s); 499 size_t len = strlen(s);
500 while (ch_isblank(**pp)) 500 while (ch_isblank(**pp))
@@ -570,113 +570,113 @@ lexi(void) @@ -570,113 +570,113 @@ lexi(void)
570 /* INDENT OFF */ 570 /* INDENT OFF */
571 case '(': lsym = lsym_lparen; next_unary = true; break; 571 case '(': lsym = lsym_lparen; next_unary = true; break;
572 case ')': lsym = lsym_rparen; next_unary = false; break; 572 case ')': lsym = lsym_rparen; next_unary = false; break;
573 case '[': lsym = lsym_lbracket; next_unary = true; break; 573 case '[': lsym = lsym_lbracket; next_unary = true; break;
574 case ']': lsym = lsym_rbracket; next_unary = false; break; 574 case ']': lsym = lsym_rbracket; next_unary = false; break;
575 case '{': lsym = lsym_lbrace; next_unary = true; break; 575 case '{': lsym = lsym_lbrace; next_unary = true; break;
576 case '}': lsym = lsym_rbrace; next_unary = true; break; 576 case '}': lsym = lsym_rbrace; next_unary = true; break;
577 case '.': lsym = lsym_period; next_unary = false; break; 577 case '.': lsym = lsym_period; next_unary = false; break;
578 case '?': lsym = lsym_question; next_unary = true; break; 578 case '?': lsym = lsym_question; next_unary = true; break;
579 case ',': lsym = lsym_comma; next_unary = true; break; 579 case ',': lsym = lsym_comma; next_unary = true; break;
580 case ';': lsym = lsym_semicolon; next_unary = true; break; 580 case ';': lsym = lsym_semicolon; next_unary = true; break;
581 /* INDENT ON */ 581 /* INDENT ON */
582 582
583 case '-': 
584 case '+': 583 case '+':
 584 case '-':
585 lsym = ps.next_unary ? lsym_unary_op : lsym_binary_op; 585 lsym = ps.next_unary ? lsym_unary_op : lsym_binary_op;
586 next_unary = true; 586 next_unary = true;
587 587
588 /* '++' or '--' */ 588 /* '++' or '--' */
589 if (inp_p[0] == token.s[token.len - 1]) { 589 if (*inp_p == token.s[token.len - 1]) {
590 token_add_char(*inp_p++); 590 token_add_char(*inp_p++);
591 if (ps.prev_lsym == lsym_word || 591 if (ps.prev_lsym == lsym_word ||
592 ps.prev_lsym == lsym_rparen || 592 ps.prev_lsym == lsym_rparen ||
593 ps.prev_lsym == lsym_rbracket) { 593 ps.prev_lsym == lsym_rbracket) {
594 lsym = ps.next_unary 594 lsym = ps.next_unary
595 ? lsym_unary_op : lsym_postfix_op; 595 ? lsym_unary_op : lsym_postfix_op;
596 next_unary = false; 596 next_unary = false;
597 } 597 }
598 598
599 } else if (inp_p[0] == '=') { /* '+=' or '-=' */ 599 } else if (*inp_p == '=') { /* '+=' or '-=' */
600 token_add_char(*inp_p++); 600 token_add_char(*inp_p++);
601 601
602 } else if (inp_p[0] == '>') { /* '->' */ 602 } else if (*inp_p == '>') { /* '->' */
603 token_add_char(*inp_p++); 603 token_add_char(*inp_p++);
604 lsym = lsym_unary_op; 604 lsym = lsym_unary_op;
605 next_unary = false; 605 next_unary = false;
606 ps.want_blank = false; 606 ps.want_blank = false;
607 } 607 }
608 break; 608 break;
609 609
610 case ':': 610 case ':':
611 lsym = ps.quest_level > 0 611 lsym = ps.quest_level > 0
612 ? (ps.quest_level--, lsym_question_colon) 612 ? (ps.quest_level--, lsym_question_colon)
613 : ps.in_var_decl ? lsym_other_colon : lsym_label_colon; 613 : ps.in_var_decl ? lsym_other_colon : lsym_label_colon;
614 next_unary = true; 614 next_unary = true;
615 break; 615 break;
616 616
617 case '*': 617 case '*':
618 if (inp_p[0] == '=') { 618 if (*inp_p == '=') {
619 token_add_char(*inp_p++); 619 token_add_char(*inp_p++);
620 lsym = lsym_binary_op; 620 lsym = lsym_binary_op;
621 } else if (is_asterisk_pointer()) { 621 } else if (is_asterisk_pointer()) {
622 lex_asterisk_pointer(); 622 lex_asterisk_pointer();
623 lsym = lsym_unary_op; 623 lsym = lsym_unary_op;
624 } else 624 } else
625 lsym = lsym_binary_op; 625 lsym = lsym_binary_op;
626 next_unary = true; 626 next_unary = true;
627 break; 627 break;
628 628
629 case '=': 629 case '=':
630 if (ps.in_var_decl) 630 if (ps.in_var_decl)
631 ps.in_init = true; 631 ps.in_init = true;
632 if (inp_p[0] == '=') 632 if (*inp_p == '=')
633 token_add_char(*inp_p++); 633 token_add_char(*inp_p++);
634 lsym = lsym_binary_op; 634 lsym = lsym_binary_op;
635 next_unary = true; 635 next_unary = true;
636 break; 636 break;
637 637
638 case '>': 638 case '>':
639 case '<': 639 case '<':
640 case '!': /* ops like <, <<, <=, !=, etc. */ 640 case '!': /* ops like <, <<, <=, !=, etc. */
641 if (inp_p[0] == '>' || inp_p[0] == '<' || inp_p[0] == '=') 641 if (*inp_p == '>' || *inp_p == '<' || *inp_p == '=')
642 token_add_char(*inp_p++); 642 token_add_char(*inp_p++);
643 if (inp_p[0] == '=') 643 if (*inp_p == '=')
644 token_add_char(*inp_p++); 644 token_add_char(*inp_p++);
645 lsym = ps.next_unary ? lsym_unary_op : lsym_binary_op; 645 lsym = ps.next_unary ? lsym_unary_op : lsym_binary_op;
646 next_unary = true; 646 next_unary = true;
647 break; 647 break;
648 648
649 case '\'': 649 case '\'':
650 case '"': 650 case '"':
651 lex_char_or_string(); 651 lex_char_or_string();
652 lsym = lsym_word; 652 lsym = lsym_word;
653 next_unary = false; 653 next_unary = false;
654 break; 654 break;
655 655
656 default: 656 default:
657 if (token.s[token.len - 1] == '/' 657 if (token.s[token.len - 1] == '/'
658 && (inp_p[0] == '*' || inp_p[0] == '/')) { 658 && (*inp_p == '*' || *inp_p == '/')) {
659 enum indent_enabled prev = indent_enabled; 659 enum indent_enabled prev = indent_enabled;
660 lex_indent_comment(); 660 lex_indent_comment();
661 if (prev == indent_on && indent_enabled == indent_off) 661 if (prev == indent_on && indent_enabled == indent_off)
662 buf_clear(&out.indent_off_text); 662 buf_clear(&out.indent_off_text);
663 token_add_char(*inp_p++); 663 token_add_char(*inp_p++);
664 lsym = lsym_comment; 664 lsym = lsym_comment;
665 next_unary = ps.next_unary; 665 next_unary = ps.next_unary;
666 break; 666 break;
667 } 667 }
668 668
669 /* punctuation like '%', '&&', '/', '^', '||', '~' */ 669 /* punctuation like '%', '&&', '/', '^', '||', '~' */
670 lsym = ps.next_unary ? lsym_unary_op : lsym_binary_op; 670 lsym = ps.next_unary ? lsym_unary_op : lsym_binary_op;
671 if (inp_p[0] == token.s[token.len - 1]) 671 if (*inp_p == token.s[token.len - 1])
672 token_add_char(*inp_p++), lsym = lsym_binary_op; 672 token_add_char(*inp_p++), lsym = lsym_binary_op;
673 if (inp_p[0] == '=') 673 if (*inp_p == '=')
674 token_add_char(*inp_p++), lsym = lsym_binary_op; 674 token_add_char(*inp_p++), lsym = lsym_binary_op;
675 675
676 next_unary = true; 676 next_unary = true;
677 } 677 }
678 678
679 ps.next_unary = next_unary; 679 ps.next_unary = next_unary;
680 680
681 return lsym; 681 return lsym;
682} 682}

cvs diff -r1.77 -r1.78 src/usr.bin/indent/parse.c (expand / switch to unified diff)

--- src/usr.bin/indent/parse.c 2023/06/14 20:46:08 1.77
+++ src/usr.bin/indent/parse.c 2023/06/17 22:28:49 1.78
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parse.c,v 1.77 2023/06/14 20:46:08 rillig Exp $ */ 1/* $NetBSD: parse.c,v 1.78 2023/06/17 22:28:49 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
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE. 37 * SUCH DAMAGE.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: parse.c,v 1.77 2023/06/14 20:46:08 rillig Exp $"); 41__RCSID("$NetBSD: parse.c,v 1.78 2023/06/17 22:28:49 rillig Exp $");
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44 44
45#include "indent.h" 45#include "indent.h"
46 46
47/* 47/*
48 * Try to combine the statement on the top of the parse stack with the symbol 48 * Try to combine the statement on the top of the parse stack with the symbol
49 * directly below it, replacing these two symbols with a single symbol. 49 * directly below it, replacing these two symbols with a single symbol.
50 */ 50 */
51static bool 51static bool
52psyms_reduce_stmt(void) 52psyms_reduce_stmt(void)
53{ 53{
54 struct psym_stack *psyms = &ps.psyms; 54 struct psym_stack *psyms = &ps.psyms;
@@ -58,27 +58,27 @@ psyms_reduce_stmt(void) @@ -58,27 +58,27 @@ psyms_reduce_stmt(void)
58 psyms->sym[psyms->len-- - 2] = psym_stmt; 58 psyms->sym[psyms->len-- - 2] = psym_stmt;
59 return true; 59 return true;
60 60
61 case psym_do: 61 case psym_do:
62 psyms->sym[psyms->len-- - 2] = psym_do_stmt; 62 psyms->sym[psyms->len-- - 2] = psym_do_stmt;
63 ps.ind_level_follow = psyms->ind_level[psyms->len - 1]; 63 ps.ind_level_follow = psyms->ind_level[psyms->len - 1];
64 return true; 64 return true;
65 65
66 case psym_if_expr: 66 case psym_if_expr:
67 psyms->sym[psyms->len-- - 2] = psym_if_expr_stmt; 67 psyms->sym[psyms->len-- - 2] = psym_if_expr_stmt;
68 size_t i = psyms->len - 2; 68 size_t i = psyms->len - 2;
69 while (psyms->sym[i] != psym_stmt && 69 while (psyms->sym[i] != psym_stmt &&
70 psyms->sym[i] != psym_lbrace_block) 70 psyms->sym[i] != psym_lbrace_block)
71 --i; 71 i--;
72 ps.ind_level_follow = psyms->ind_level[i]; 72 ps.ind_level_follow = psyms->ind_level[i];
73 /* For the time being, assume that there is no 'else' on this 73 /* For the time being, assume that there is no 'else' on this
74 * 'if', and set the indentation level accordingly. If an 74 * 'if', and set the indentation level accordingly. If an
75 * 'else' is scanned, it will be fixed up later. */ 75 * 'else' is scanned, it will be fixed up later. */
76 return true; 76 return true;
77 77
78 case psym_switch_expr: 78 case psym_switch_expr:
79 case psym_decl: 79 case psym_decl:
80 case psym_if_expr_stmt_else: 80 case psym_if_expr_stmt_else:
81 case psym_for_exprs: 81 case psym_for_exprs:
82 case psym_while_expr: 82 case psym_while_expr:
83 psyms->sym[psyms->len-- - 2] = psym_stmt; 83 psyms->sym[psyms->len-- - 2] = psym_stmt;
84 ps.ind_level_follow = psyms->ind_level[psyms->len - 1]; 84 ps.ind_level_follow = psyms->ind_level[psyms->len - 1];
@@ -160,36 +160,36 @@ parse(parser_symbol psym) @@ -160,36 +160,36 @@ parse(parser_symbol psym)
160 psyms_reduce(); 160 psyms_reduce();
161 } 161 }
162 } 162 }
163 163
164 switch (psym) { 164 switch (psym) {
165 165
166 case psym_lbrace_block: 166 case psym_lbrace_block:
167 case psym_lbrace_struct: 167 case psym_lbrace_struct:
168 case psym_lbrace_union: 168 case psym_lbrace_union:
169 case psym_lbrace_enum: 169 case psym_lbrace_enum:
170 ps.break_after_comma = false; 170 ps.break_after_comma = false;
171 if (psyms->sym[psyms->len - 1] == psym_decl 171 if (psyms->sym[psyms->len - 1] == psym_decl
172 || psyms->sym[psyms->len - 1] == psym_stmt) 172 || psyms->sym[psyms->len - 1] == psym_stmt)
173 ++ps.ind_level_follow; 173 ps.ind_level_follow++;
174 else if (code.len == 0) { 174 else if (code.len == 0) {
175 /* It is part of a while, for, etc. */ 175 /* It is part of a while, for, etc. */
176 --ps.ind_level; 176 ps.ind_level--;
177 177
178 /* for a switch, brace should be two levels out from 178 /* for a switch, brace should be two levels out from
179 * the code */ 179 * the code */
180 if (psyms->sym[psyms->len - 1] == psym_switch_expr 180 if (psyms->sym[psyms->len - 1] == psym_switch_expr
181 && opt.case_indent >= 1.0F) 181 && opt.case_indent >= 1.0F)
182 --ps.ind_level; 182 ps.ind_level--;
183 } 183 }
184 184
185 ps_push(psym, false); 185 ps_push(psym, false);
186 ps_push(psym_stmt, true); 186 ps_push(psym_stmt, true);
187 break; 187 break;
188 188
189 case psym_rbrace: 189 case psym_rbrace:
190 /* stack should have <lbrace> <stmt> or <lbrace> <decl> */ 190 /* stack should have <lbrace> <stmt> or <lbrace> <decl> */
191 if (!(psyms->len >= 2 191 if (!(psyms->len >= 2
192 && is_lbrace(psyms->sym[psyms->len - 2]))) { 192 && is_lbrace(psyms->sym[psyms->len - 2]))) {
193 diag(1, "Statement nesting error"); 193 diag(1, "Statement nesting error");
194 break; 194 break;
195 } 195 }
@@ -238,26 +238,26 @@ parse(parser_symbol psym) @@ -238,26 +238,26 @@ parse(parser_symbol psym)
238 238
239 case psym_switch_expr: 239 case psym_switch_expr:
240 ps_push(psym_switch_expr, true); 240 ps_push(psym_switch_expr, true);
241 ps.ind_level_follow += (int)opt.case_indent + 1; 241 ps.ind_level_follow += (int)opt.case_indent + 1;
242 break; 242 break;
243 243
244 case psym_while_expr: 244 case psym_while_expr:
245 if (psyms->sym[psyms->len - 1] == psym_do_stmt) { 245 if (psyms->sym[psyms->len - 1] == psym_do_stmt) {
246 ps.ind_level = ps.ind_level_follow = 246 ps.ind_level = ps.ind_level_follow =
247 psyms->ind_level[psyms->len - 1]; 247 psyms->ind_level[psyms->len - 1];
248 ps_push(psym_while_expr, false); 248 ps_push(psym_while_expr, false);
249 } else { 249 } else {
250 ps_push(psym_while_expr, true); 250 ps_push(psym_while_expr, true);
251 ++ps.ind_level_follow; 251 ps.ind_level_follow++;
252 } 252 }
253 break; 253 break;
254 254
255 default: 255 default:
256 diag(1, "Unknown code to parser"); 256 diag(1, "Unknown code to parser");
257 return; 257 return;
258 } 258 }
259 259
260 debug_psyms_stack("before reduction"); 260 debug_psyms_stack("before reduction");
261 psyms_reduce(); 261 psyms_reduce();
262 debug_psyms_stack("after reduction"); 262 debug_psyms_stack("after reduction");
263} 263}

cvs diff -r1.166 -r1.167 src/usr.bin/indent/pr_comment.c (expand / switch to unified diff)

--- src/usr.bin/indent/pr_comment.c 2023/06/16 11:27:49 1.166
+++ src/usr.bin/indent/pr_comment.c 2023/06/17 22:28:49 1.167
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pr_comment.c,v 1.166 2023/06/16 11:27:49 rillig Exp $ */ 1/* $NetBSD: pr_comment.c,v 1.167 2023/06/17 22:28:49 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
@@ -28,40 +28,40 @@ @@ -28,40 +28,40 @@
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE. 37 * SUCH DAMAGE.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__RCSID("$NetBSD: pr_comment.c,v 1.166 2023/06/16 11:27:49 rillig Exp $"); 41__RCSID("$NetBSD: pr_comment.c,v 1.167 2023/06/17 22:28:49 rillig Exp $");
42 42
43#include <string.h> 43#include <string.h>
44 44
45#include "indent.h" 45#include "indent.h"
46 46
47static void 47static void
48com_add_char(char ch) 48com_add_char(char ch)
49{ 49{
50 buf_add_char(&com, ch); 50 buf_add_char(&com, ch);
51} 51}
52 52
53static void 53static void
54com_add_delim(void) 54com_add_star(void)
55{ 55{
56 if (opt.star_comment_cont) 56 if (opt.star_comment_cont)
57 buf_add_chars(&com, " * ", 3); 57 buf_add_chars(&com, " * ", 3);
58} 58}
59 59
60static bool 60static bool
61fits_in_one_line(int max_line_length) 61fits_in_one_line(int max_line_length)
62{ 62{
63 for (const char *start = inp_p, *p = start; *p != '\n'; p++) { 63 for (const char *start = inp_p, *p = start; *p != '\n'; p++) {
64 if (p[0] == '*' && p[1] == '/') { 64 if (p[0] == '*' && p[1] == '/') {
65 while (p - inp_p >= 2 65 while (p - inp_p >= 2
66 && ch_isblank(p[-1]) 66 && ch_isblank(p[-1])
67 && ch_isblank(p[-2])) 67 && ch_isblank(p[-2]))
@@ -69,27 +69,27 @@ fits_in_one_line(int max_line_length) @@ -69,27 +69,27 @@ fits_in_one_line(int max_line_length)
69 int ind = ind_add(ps.comment_ind + 3, 69 int ind = ind_add(ps.comment_ind + 3,
70 start, (size_t)(p - start)); 70 start, (size_t)(p - start));
71 ind += p == start || ch_isblank(p[-1]) ? 2 : 3; 71 ind += p == start || ch_isblank(p[-1]) ? 2 : 3;
72 return ind <= max_line_length; 72 return ind <= max_line_length;
73 } 73 }
74 } 74 }
75 return false; 75 return false;
76} 76}
77 77
78static void 78static void
79analyze_comment(bool *p_may_wrap, bool *p_delim, int *p_line_length) 79analyze_comment(bool *p_may_wrap, bool *p_delim, int *p_line_length)
80{ 80{
81 bool may_wrap = true; 81 bool may_wrap = true;
82 bool delim = false; 82 bool delim = false; // only relevant if may_wrap
83 int ind; 83 int ind;
84 int line_length = opt.max_line_length; 84 int line_length = opt.max_line_length;
85 85
86 if (inp_p - inp.s == 2 && !opt.format_col1_comments) { 86 if (inp_p - inp.s == 2 && !opt.format_col1_comments) {
87 may_wrap = false; 87 may_wrap = false;
88 ind = 0; 88 ind = 0;
89 } else { 89 } else {
90 if (inp_p[0] == '-' || inp_p[0] == '*' || 90 if (inp_p[0] == '-' || inp_p[0] == '*' ||
91 token.s[token.len - 1] == '/' || 91 token.s[token.len - 1] == '/' ||
92 (inp_p[0] == '\n' && !opt.format_block_comments)) 92 (inp_p[0] == '\n' && !opt.format_block_comments))
93 may_wrap = false; 93 may_wrap = false;
94 if (code.len == 0 && inp_p[strspn(inp_p, "*")] == '\n') 94 if (code.len == 0 && inp_p[strspn(inp_p, "*")] == '\n')
95 out.line_kind = lk_block_comment; 95 out.line_kind = lk_block_comment;
@@ -97,35 +97,35 @@ analyze_comment(bool *p_may_wrap, bool * @@ -97,35 +97,35 @@ analyze_comment(bool *p_may_wrap, bool *
97 if (com.len > 0) 97 if (com.len > 0)
98 output_line(); 98 output_line();
99 if (lab.len == 0 && code.len == 0) { 99 if (lab.len == 0 && code.len == 0) {
100 ind = (ps.ind_level - opt.unindent_displace) 100 ind = (ps.ind_level - opt.unindent_displace)
101 * opt.indent_size; 101 * opt.indent_size;
102 if (ind <= 0) 102 if (ind <= 0)
103 ind = opt.format_col1_comments ? 0 : 1; 103 ind = opt.format_col1_comments ? 0 : 1;
104 line_length = opt.block_comment_max_line_length; 104 line_length = opt.block_comment_max_line_length;
105 if (may_wrap && inp_p[0] == '\n') 105 if (may_wrap && inp_p[0] == '\n')
106 delim = true; 106 delim = true;
107 if (may_wrap && opt.comment_delimiter_on_blank_line) 107 if (may_wrap && opt.comment_delimiter_on_blank_line)
108 delim = true; 108 delim = true;
109 } else { 109 } else {
110 int target_ind = code.len > 0 110 int min_ind = code.len > 0
111 ? ind_add(compute_code_indent(), code.s, code.len) 111 ? ind_add(compute_code_indent(), code.s, code.len)
112 : ind_add(compute_label_indent(), lab.s, lab.len); 112 : ind_add(compute_label_indent(), lab.s, lab.len);
113 113
114 ind = ps.line_has_decl || ps.ind_level == 0 114 ind = ps.line_has_decl || ps.ind_level == 0
115 ? opt.decl_comment_column - 1 115 ? opt.decl_comment_column - 1
116 : opt.comment_column - 1; 116 : opt.comment_column - 1;
117 if (ind <= target_ind) 117 if (ind <= min_ind)
118 ind = next_tab(target_ind); 118 ind = next_tab(min_ind);
119 if (ind + 25 > line_length) 119 if (ind + 25 > line_length)
120 line_length = ind + 25; 120 line_length = ind + 25;
121 } 121 }
122 } 122 }
123 123
124 if (!may_wrap) { 124 if (!may_wrap) {
125 /* Find out how much indentation there was originally, because 125 /* Find out how much indentation there was originally, because
126 * that much will have to be ignored by output_line. */ 126 * that much will have to be ignored by output_line. */
127 size_t len = (size_t)(inp_p - 2 - inp.s); 127 size_t len = (size_t)(inp_p - 2 - inp.s);
128 ps.comment_shift = -ind_add(0, inp.s, len); 128 ps.comment_shift = -ind_add(0, inp.s, len);
129 } else { 129 } else {
130 ps.comment_shift = 0; 130 ps.comment_shift = 0;
131 if (!(inp_p[0] == '\t' && !ch_isblank(inp_p[1]))) 131 if (!(inp_p[0] == '\t' && !ch_isblank(inp_p[1])))
@@ -144,91 +144,95 @@ copy_comment_start(bool may_wrap, bool * @@ -144,91 +144,95 @@ copy_comment_start(bool may_wrap, bool *
144{ 144{
145 ps.comment_cont = false; 145 ps.comment_cont = false;
146 com_add_char('/'); 146 com_add_char('/');
147 com_add_char(token.s[token.len - 1]); /* either '*' or '/' */ 147 com_add_char(token.s[token.len - 1]); /* either '*' or '/' */
148 148
149 if (may_wrap) { 149 if (may_wrap) {
150 if (!ch_isblank(inp_p[0])) 150 if (!ch_isblank(inp_p[0]))
151 com_add_char(' '); 151 com_add_char(' ');
152 152
153 if (*delim && fits_in_one_line(line_length)) 153 if (*delim && fits_in_one_line(line_length))
154 *delim = false; 154 *delim = false;
155 if (*delim) { 155 if (*delim) {
156 output_line(); 156 output_line();
157 com_add_delim(); 157 com_add_star();
158 } 158 }
159 } 159 }
160} 160}
161 161
162static void 162static void
163copy_comment_wrap_text(int line_length, ssize_t *last_blank) 163copy_comment_wrap_text(int line_length, ssize_t *last_blank)
164{ 164{
165 int now_len = ind_add(ps.comment_ind, com.s, com.len); 165 int ind = ind_add(ps.comment_ind, com.s, com.len);
166 for (;;) { 166 for (;;) {
167 char ch = inp_next(); 167 char ch = inp_next();
168 if (ch_isblank(ch)) 168 if (ch_isblank(ch))
169 *last_blank = (ssize_t)com.len; 169 *last_blank = (ssize_t)com.len;
170 com_add_char(ch); 170 com_add_char(ch);
171 now_len++; 171 ind++;
172 if (memchr("*\n\r\b\t", inp_p[0], 6) != NULL) 172 if (memchr("*\n\r\b\t", inp_p[0], 6) != NULL)
173 break; 173 break;
174 if (now_len >= line_length && *last_blank != -1) 174 if (ind >= line_length && *last_blank != -1)
175 break; 175 break;
176 } 176 }
177 177
178 if (now_len <= line_length) 178 if (ind <= line_length)
179 return; 179 return;
180 if (ch_isspace(com.s[com.len - 1])) 180 if (ch_isspace(com.s[com.len - 1]))
181 return; 181 return;
182 182
183 if (*last_blank == -1) { 183 if (*last_blank == -1) {
184 /* only a single word in this line */ 184 /* only a single word in this line */
185 output_line(); 185 output_line();
186 com_add_delim(); 186 com_add_star();
187 return; 187 return;
188 } 188 }
189 189
190 const char *last_word_s = com.s + *last_blank + 1; 190 // Move the overlong word to the next line.
 191 const char *last_word = com.s + *last_blank + 1;
191 size_t last_word_len = com.len - (size_t)(*last_blank + 1); 192 size_t last_word_len = com.len - (size_t)(*last_blank + 1);
192 com.len = (size_t)*last_blank; 193 com.len = (size_t)*last_blank;
 194 buf_terminate(&com);
193 output_line(); 195 output_line();
194 com_add_delim(); 196 com_add_star();
195 197
196 /* Assume that output_line and com_add_delim don't invalidate the 198 /* Assume that output_line and com_add_delim left the "unused" part of
197 * "unused" part of the buffer beyond com.s + com.len. */ 199 * the now truncated buffer beyond com.s + com.len as-is. */
198 memmove(com.s + com.len, last_word_s, last_word_len); 200 memmove(com.s + com.len, last_word, last_word_len);
199 com.len += last_word_len; 201 com.len += last_word_len;
 202 buf_terminate(&com);
200 *last_blank = -1; 203 *last_blank = -1;
201} 204}
202 205
 206/* In a comment that is re-wrapped, handle a single newline character. */
203static bool 207static bool
204copy_comment_wrap_newline(ssize_t *last_blank, bool seen_newline) 208copy_comment_wrap_newline(ssize_t *last_blank, bool seen_newline)
205{ 209{
206 *last_blank = -1; 210 *last_blank = -1;
207 if (seen_newline) { 211 if (seen_newline) {
208 if (com.len == 0) 212 if (com.len == 0)
209 com_add_char(' '); /* force empty output line */ 213 com_add_char(' '); /* force empty output line */
210 if (com.len > 3) { 214 if (com.len > 3) {
211 output_line(); 215 output_line();
212 com_add_delim(); 216 com_add_star();
213 } 217 }
214 output_line(); 218 output_line();
215 com_add_delim(); 219 com_add_star();
216 } else { 220 } else {
217 if (!(com.len > 0 && ch_isblank(com.s[com.len - 1]))) 221 if (!(com.len > 0 && ch_isblank(com.s[com.len - 1])))
218 com_add_char(' '); 222 com_add_char(' ');
219 *last_blank = (int)com.len - 1; 223 *last_blank = (int)com.len - 1;
220 } 224 }
221 ++line_no; 225 line_no++;
222 226
223 /* flush any blanks and/or tabs at start of next line */ 227 /* flush any blanks and/or tabs at start of next line */
224 inp_skip(); /* '\n' */ 228 inp_skip(); /* '\n' */
225 while (ch_isblank(inp_p[0])) 229 while (ch_isblank(inp_p[0]))
226 inp_p++; 230 inp_p++;
227 if (inp_p[0] == '*' && inp_p[1] == '/') 231 if (inp_p[0] == '*' && inp_p[1] == '/')
228 return false; 232 return false;
229 if (inp_p[0] == '*') { 233 if (inp_p[0] == '*') {
230 inp_p++; 234 inp_p++;
231 while (ch_isblank(inp_p[0])) 235 while (ch_isblank(inp_p[0]))
232 inp_p++; 236 inp_p++;
233 } 237 }
234 238
@@ -236,52 +240,46 @@ copy_comment_wrap_newline(ssize_t *last_ @@ -236,52 +240,46 @@ copy_comment_wrap_newline(ssize_t *last_
236} 240}
237 241
238static void 242static void
239copy_comment_wrap_finish(int line_length, bool delim) 243copy_comment_wrap_finish(int line_length, bool delim)
240{ 244{
241 if (delim) { 245 if (delim) {
242 if (com.len > 3) 246 if (com.len > 3)
243 output_line(); 247 output_line();
244 else 248 else
245 buf_clear(&com); 249 buf_clear(&com);
246 com_add_char(' '); 250 com_add_char(' ');
247 } else { 251 } else {
248 size_t len = com.len; 252 size_t len = com.len;
 253 // XXX: This loop differs from the one below.
249 while (ch_isblank(com.s[len - 1])) 254 while (ch_isblank(com.s[len - 1]))
250 len--; 255 len--;
251 int end_ind = ind_add(ps.comment_ind, com.s, len); 256 if (ind_add(ps.comment_ind, com.s, len) + 3 > line_length)
252 if (end_ind + 3 > line_length) 
253 output_line(); 257 output_line();
254 } 258 }
255 259
256 while (com.len >= 2 260 while (com.len >= 2
257 && ch_isblank(com.s[com.len - 1]) 261 && ch_isblank(com.s[com.len - 1])
258 && ch_isblank(com.s[com.len - 2])) 262 && ch_isblank(com.s[com.len - 2]))
259 com.len--; 263 com.len--;
260 buf_terminate(&com); 264 buf_terminate(&com);
261 265
262 inp_p += 2; 266 inp_p += 2;
263 if (com.len > 0 && ch_isblank(com.s[com.len - 1])) 267 if (com.len > 0 && ch_isblank(com.s[com.len - 1]))
264 buf_add_chars(&com, "*/", 2); 268 buf_add_chars(&com, "*/", 2);
265 else 269 else
266 buf_add_chars(&com, " */", 3); 270 buf_add_chars(&com, " */", 3);
267} 271}
268 272
269/* 
270 * Copy characters from 'inp' to 'com'. Try to keep comments from going over 
271 * the maximum line length. To do that, remember where the last blank, tab, or 
272 * newline was. When a line is filled, print up to the last blank and continue 
273 * copying. 
274 */ 
275static void 273static void
276copy_comment_wrap(int line_length, bool delim) 274copy_comment_wrap(int line_length, bool delim)
277{ 275{
278 ssize_t last_blank = -1; /* index of the last blank in 'com' */ 276 ssize_t last_blank = -1; /* index of the last blank in 'com' */
279 bool seen_newline = false; 277 bool seen_newline = false;
280 278
281 for (;;) { 279 for (;;) {
282 if (inp_p[0] == '\n') { 280 if (inp_p[0] == '\n') {
283 if (had_eof) 281 if (had_eof)
284 goto unterminated_comment; 282 goto unterminated_comment;
285 if (!copy_comment_wrap_newline(&last_blank, 283 if (!copy_comment_wrap_newline(&last_blank,
286 seen_newline)) 284 seen_newline))
287 break; 285 break;
@@ -312,44 +310,40 @@ copy_comment_nowrap(void) @@ -312,44 +310,40 @@ copy_comment_nowrap(void)
312 if (kind == '/') 310 if (kind == '/')
313 return; 311 return;
314 312
315 if (had_eof) { 313 if (had_eof) {
316 diag(1, "Unterminated comment"); 314 diag(1, "Unterminated comment");
317 output_line(); 315 output_line();
318 return; 316 return;
319 } 317 }
320 318
321 if (com.len == 0) 319 if (com.len == 0)
322 com_add_char(' '); /* force output of an 320 com_add_char(' '); /* force output of an
323 * empty line */ 321 * empty line */
324 output_line(); 322 output_line();
325 ++line_no; 323 line_no++;
326 inp_skip(); 324 inp_skip();
327 continue; 325 continue;
328 } 326 }
329 327
330 com_add_char(*inp_p++); 328 com_add_char(*inp_p++);
331 if (com.len >= 2 329 if (com.len >= 2
332 && com.s[com.len - 2] == '*' 330 && com.s[com.len - 2] == '*'
333 && com.s[com.len - 1] == '/' 331 && com.s[com.len - 1] == '/'
334 && kind == '*') 332 && kind == '*')
335 return; 333 return;
336 } 334 }
337} 335}
338 336
339/* 
340 * Scan, reformat and output a single comment, which is either a block comment 
341 * starting with '/' '*' or an end-of-line comment starting with '//'. 
342 */ 
343void 337void
344process_comment(void) 338process_comment(void)
345{ 339{
346 bool may_wrap, delim; 340 bool may_wrap, delim;
347 int line_length; 341 int line_length;
348 342
349 analyze_comment(&may_wrap, &delim, &line_length); 343 analyze_comment(&may_wrap, &delim, &line_length);
350 copy_comment_start(may_wrap, &delim, line_length); 344 copy_comment_start(may_wrap, &delim, line_length);
351 if (may_wrap) 345 if (may_wrap)
352 copy_comment_wrap(line_length, delim); 346 copy_comment_wrap(line_length, delim);
353 else 347 else
354 copy_comment_nowrap(); 348 copy_comment_nowrap();
355} 349}