Module Name:    src
Committed By:   rillig
Date:           Thu Jun 15 09:19:07 UTC 2023

Modified Files:
        src/tests/usr.bin/indent: fmt_decl.c lsym_case_label.c lsym_funcname.c
            lsym_lbrace.c lsym_rparen_or_rbracket.c lsym_semicolon.c lsym_tag.c
            lsym_type_outside_parentheses.c opt_bacc.c opt_eei.c ps_ind_level.c
        src/usr.bin/indent: args.c indent.c io.c

Log Message:
indent: miscellaneous cleanups, more tests for edge cases


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/tests/usr.bin/indent/fmt_decl.c
cvs rdiff -u -r1.10 -r1.11 src/tests/usr.bin/indent/lsym_case_label.c
cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/indent/lsym_funcname.c
cvs rdiff -u -r1.8 -r1.9 src/tests/usr.bin/indent/lsym_lbrace.c \
    src/tests/usr.bin/indent/ps_ind_level.c
cvs rdiff -u -r1.4 -r1.5 src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c \
    src/tests/usr.bin/indent/lsym_semicolon.c
cvs rdiff -u -r1.7 -r1.8 src/tests/usr.bin/indent/lsym_tag.c
cvs rdiff -u -r1.6 -r1.7 \
    src/tests/usr.bin/indent/lsym_type_outside_parentheses.c
cvs rdiff -u -r1.12 -r1.13 src/tests/usr.bin/indent/opt_bacc.c
cvs rdiff -u -r1.14 -r1.15 src/tests/usr.bin/indent/opt_eei.c
cvs rdiff -u -r1.84 -r1.85 src/usr.bin/indent/args.c
cvs rdiff -u -r1.368 -r1.369 src/usr.bin/indent/indent.c
cvs rdiff -u -r1.221 -r1.222 src/usr.bin/indent/io.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/usr.bin/indent/fmt_decl.c
diff -u src/tests/usr.bin/indent/fmt_decl.c:1.56 src/tests/usr.bin/indent/fmt_decl.c:1.57
--- src/tests/usr.bin/indent/fmt_decl.c:1.56	Thu Jun 15 08:40:20 2023
+++ src/tests/usr.bin/indent/fmt_decl.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: fmt_decl.c,v 1.56 2023/06/15 08:40:20 rillig Exp $	*/
+/*	$NetBSD: fmt_decl.c,v 1.57 2023/06/15 09:19:07 rillig Exp $	*/
 
 /*
  * Tests for declarations of global variables, external functions, and local
@@ -1183,3 +1183,20 @@ multi_line = (int[]){
 	};
 }
 //indent end
+
+
+/*
+ *
+ */
+//indent input
+int
+old_style(a)
+	struct {
+		int		member;
+	}		a;
+{
+	stmt;
+}
+//indent end
+
+//indent run-equals-input

Index: src/tests/usr.bin/indent/lsym_case_label.c
diff -u src/tests/usr.bin/indent/lsym_case_label.c:1.10 src/tests/usr.bin/indent/lsym_case_label.c:1.11
--- src/tests/usr.bin/indent/lsym_case_label.c:1.10	Sat Jun 10 07:05:18 2023
+++ src/tests/usr.bin/indent/lsym_case_label.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_case_label.c,v 1.10 2023/06/10 07:05:18 rillig Exp $ */
+/* $NetBSD: lsym_case_label.c,v 1.11 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the tokens lsym_case and lsym_default, which represent the
@@ -103,3 +103,23 @@ const char *type_name = _Generic(
 //indent end
 
 //indent run-equals-input -di0 -nlp
+
+
+/*
+ * Multi-line case expressions are rare but still should be processed in a
+ * sensible way.
+ */
+//indent input
+{
+	switch (expr) {
+// $ FIXME: The line containing the 'case' must be indented like a 'case'.
+		case 1
+		    + 2
+// $ FIXME: This continuation line must be indented by 4 columns.
+	+ 3:
+		stmt;
+	}
+}
+//indent end
+
+//indent run-equals-input -ci4

Index: src/tests/usr.bin/indent/lsym_funcname.c
diff -u src/tests/usr.bin/indent/lsym_funcname.c:1.5 src/tests/usr.bin/indent/lsym_funcname.c:1.6
--- src/tests/usr.bin/indent/lsym_funcname.c:1.5	Mon May 22 23:01:27 2023
+++ src/tests/usr.bin/indent/lsym_funcname.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_funcname.c,v 1.5 2023/05/22 23:01:27 rillig Exp $ */
+/* $NetBSD: lsym_funcname.c,v 1.6 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the token lsym_funcname, which is the name of a function, but only
@@ -19,3 +19,17 @@ function(void)
 //indent end
 
 //indent run-equals-input
+
+
+/*
+ * The comment after the return type of a function definition is a code
+ * comment, not a declaration comment.
+ */
+//indent input
+void				// comment
+function_with_comment(void)
+{
+}
+//indent end
+
+//indent run-equals-input

Index: src/tests/usr.bin/indent/lsym_lbrace.c
diff -u src/tests/usr.bin/indent/lsym_lbrace.c:1.8 src/tests/usr.bin/indent/lsym_lbrace.c:1.9
--- src/tests/usr.bin/indent/lsym_lbrace.c:1.8	Sun Jun  4 13:49:00 2023
+++ src/tests/usr.bin/indent/lsym_lbrace.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_lbrace.c,v 1.8 2023/06/04 13:49:00 rillig Exp $ */
+/* $NetBSD: lsym_lbrace.c,v 1.9 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the token lsym_lbrace, which represents a '{' in these contexts:
@@ -58,8 +58,88 @@ origin(void)
 	return (struct point){
 		.x = 0,
 		.y = 0,
-	};
+	}, actual_return_value;
 }
 //indent end
 
 //indent run-equals-input
+
+/* Ensure that the comma is not interpreted as separator for declarators. */
+//indent run-equals-input -bc
+
+
+//indent input
+{
+	const char *hello = (const char[]){
+		'h', 'e', 'l', 'l', 'o',
+	}, *world = (const char[]){
+		'w', 'o', 'r', 'l', 'd',
+	};
+}
+//indent end
+
+//indent run-equals-input -ldi0
+
+//indent run-equals-input -ldi0 -bc
+
+
+//indent input
+{
+	if (cond rparen {
+	}
+	switch (expr rparen {
+	}
+}
+//indent end
+
+//indent run
+{
+		if (cond rparen {
+		}
+		switch (expr rparen {
+		}
+}
+exit 1
+error: Standard Input:2: Unbalanced parentheses
+error: Standard Input:4: Unbalanced parentheses
+//indent end
+
+
+/*
+ * The -bl option does not force initializer braces on separate lines.
+ */
+//indent input
+struct {int member;} var = {1};
+//indent end
+
+//indent run -bl
+struct
+{
+	int		member;
+}		var = {1};
+//indent end
+
+
+/*
+ * A comment in a single-line function definition is not a declaration comment
+ * and thus not in column 25.
+ */
+//indent input
+void function(void); /* comment */
+void function(void) { /* comment */ }
+//indent end
+
+//indent run -di0
+void function(void);		/* comment */
+void
+function(void)
+{				/* comment */
+}
+//indent end
+
+//indent run -di0 -nfbs
+void function(void);		/* comment */
+void
+function(void) {		/* comment */
+}
+//indent end
Index: src/tests/usr.bin/indent/ps_ind_level.c
diff -u src/tests/usr.bin/indent/ps_ind_level.c:1.8 src/tests/usr.bin/indent/ps_ind_level.c:1.9
--- src/tests/usr.bin/indent/ps_ind_level.c:1.8	Wed Jun 14 20:46:08 2023
+++ src/tests/usr.bin/indent/ps_ind_level.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: ps_ind_level.c,v 1.8 2023/06/14 20:46:08 rillig Exp $ */
+/* $NetBSD: ps_ind_level.c,v 1.9 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * The indentation of the very first line of a file determines the
@@ -116,3 +116,18 @@ int    level_0;
      }
 }
 //indent end
+
+
+/*
+ * Having function definitions indented to the right is not supported. In that
+ * case, indent does not recognize it as a function definition, and it doesn't
+ * indent the old-style parameter declarations one level further to the right.
+ */
+//indent input
+			int		old_style(a)
+			int		a;
+			{
+			}
+//indent end
+
+//indent run-equals-input

Index: src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c
diff -u src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c:1.4 src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c:1.5
--- src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c:1.4	Sun Apr 24 10:36:37 2022
+++ src/tests/usr.bin/indent/lsym_rparen_or_rbracket.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_rparen_or_rbracket.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
+/* $NetBSD: lsym_rparen_or_rbracket.c,v 1.5 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the token lsym_rparen_or_lbracket, which represents ')' or ']',
@@ -18,3 +18,39 @@ int array[3] = {[2] = 3};
 //indent end
 
 //indent run-equals-input -di0
+
+
+//indent input
+int a = array[
+3
+];
+{
+int a = array[
+3
+];
+}
+//indent end
+
+//indent run -di0
+int a = array[
+	      3
+];
+{
+	int a = array[
+		      3
+// $ FIXME: Should be one level to the left since it is the outermost bracket.
+		];
+}
+//indent end
+
+//indent run -di0 -nlp
+int a = array[
+	3
+];
+{
+	int a = array[
+		3
+// $ FIXME: Should be one level to the left since it is the outermost bracket.
+		];
+}
+//indent end
Index: src/tests/usr.bin/indent/lsym_semicolon.c
diff -u src/tests/usr.bin/indent/lsym_semicolon.c:1.4 src/tests/usr.bin/indent/lsym_semicolon.c:1.5
--- src/tests/usr.bin/indent/lsym_semicolon.c:1.4	Sun Apr 24 10:36:37 2022
+++ src/tests/usr.bin/indent/lsym_semicolon.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_semicolon.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
+/* $NetBSD: lsym_semicolon.c,v 1.5 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the token lsym_semicolon, which represents ';' in these contexts:
@@ -41,3 +41,66 @@ function(void)
 		stmt();
 }
 //indent end
+
+
+//indent input
+{
+	switch (expr) {
+// $ FIXME: Indent the 'case' at the 'switch'.
+		case;
+		stmt;
+	case 2:
+		stmt;
+	}
+}
+//indent end
+
+//indent run-equals-input
+
+
+/*
+ * A semicolon closes all possibly open '?:' expressions, so that the next ':'
+ * is interpreted as a bit-field.
+ */
+//indent input
+struct s {
+	int a[len ? ? ? 1];
+	int bit_field:1;
+};
+//indent end
+
+//indent run-equals-input -di0
+
+
+/*
+ * A semicolon does not magically close any initializer braces that may still
+ * be open.
+ */
+//indent input
+int a = {{;
+int b = 3;
+//indent end
+
+//indent run -di0
+int a = {{;
+		int b = 3;
+exit 1
+error: Standard Input:2: Stuff missing from end of file
+//indent end
+
+
+//indent input
+{
+	int a = {{;
+	int b = 3;
+}
+//indent end
+
+//indent run -di0
+{
+	int a = {{;
+			int b = 3;
+	}
+exit 1
+error: Standard Input:4: Stuff missing from end of file
+//indent end

Index: src/tests/usr.bin/indent/lsym_tag.c
diff -u src/tests/usr.bin/indent/lsym_tag.c:1.7 src/tests/usr.bin/indent/lsym_tag.c:1.8
--- src/tests/usr.bin/indent/lsym_tag.c:1.7	Mon May 15 14:12:03 2023
+++ src/tests/usr.bin/indent/lsym_tag.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_tag.c,v 1.7 2023/05/15 14:12:03 rillig Exp $ */
+/* $NetBSD: lsym_tag.c,v 1.8 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the token lsym_tag, which represents one of the keywords
@@ -134,3 +134,20 @@ struct outer {
 //indent end
 
 //indent run-equals-input -di0
+
+
+/*
+ * The initializer of an enum constant needs to be indented like any other
+ * initializer, especially the continuation lines.
+ */
+//indent input
+enum multi_line {
+	constant = 1
+// $ TODO: Indent the continuation line.
+	+ 2
+// $ TODO: Indent the continuation line.
+	+ 3,
+};
+//indent end
+
+//indent run-equals-input

Index: src/tests/usr.bin/indent/lsym_type_outside_parentheses.c
diff -u src/tests/usr.bin/indent/lsym_type_outside_parentheses.c:1.6 src/tests/usr.bin/indent/lsym_type_outside_parentheses.c:1.7
--- src/tests/usr.bin/indent/lsym_type_outside_parentheses.c:1.6	Sun Jun  4 22:20:04 2023
+++ src/tests/usr.bin/indent/lsym_type_outside_parentheses.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: lsym_type_outside_parentheses.c,v 1.6 2023/06/04 22:20:04 rillig Exp $ */
+/* $NetBSD: lsym_type_outside_parentheses.c,v 1.7 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the token lsym_type_outside_parentheses, which represents a type
@@ -45,3 +45,13 @@ size_t hello;
 	size_t		hello;
 }
 //indent end
+
+
+/*
+ * In a sizeof expression, a type argument must be enclosed in parentheses.
+ */
+//indent input
+int sizeof_int = sizeof int;
+//indent end
+
+//indent run-equals-input -di0

Index: src/tests/usr.bin/indent/opt_bacc.c
diff -u src/tests/usr.bin/indent/opt_bacc.c:1.12 src/tests/usr.bin/indent/opt_bacc.c:1.13
--- src/tests/usr.bin/indent/opt_bacc.c:1.12	Sat May 20 10:09:03 2023
+++ src/tests/usr.bin/indent/opt_bacc.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: opt_bacc.c,v 1.12 2023/05/20 10:09:03 rillig Exp $ */
+/* $NetBSD: opt_bacc.c,v 1.13 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the options '-bacc' and '-nbacc' ("blank line around conditional
@@ -128,3 +128,33 @@ int outer_below;
 //indent end
 
 //indent run-equals-input -di0 -nbacc
+
+
+//indent input
+/* before */
+#if 0
+/* between if and else */
+#else
+#if 1
+#endif
+#endif
+/* after */
+//indent end
+
+//indent run -bacc
+/* before */
+// $ XXX: The 'before' comment may refer to the '#if', so it is not obvious
+// $ XXX: that this blank line is useful.
+
+#if 0
+/* between if and else */
+#else
+// $ XXX: This blank line looks unintended, as both lines are preprocessing
+// $ XXX: directives.
+
+#if 1
+#endif
+#endif
+
+/* after */
+//indent end

Index: src/tests/usr.bin/indent/opt_eei.c
diff -u src/tests/usr.bin/indent/opt_eei.c:1.14 src/tests/usr.bin/indent/opt_eei.c:1.15
--- src/tests/usr.bin/indent/opt_eei.c:1.14	Fri Jun  9 08:10:58 2023
+++ src/tests/usr.bin/indent/opt_eei.c	Thu Jun 15 09:19:07 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: opt_eei.c,v 1.14 2023/06/09 08:10:58 rillig Exp $ */
+/* $NetBSD: opt_eei.c,v 1.15 2023/06/15 09:19:07 rillig Exp $ */
 
 /*
  * Tests for the options '-eei' and '-neei'.
@@ -211,9 +211,6 @@ b)
 //indent end
 
 
-/*
- *
- */
 //indent input
 {
 	if (((

Index: src/usr.bin/indent/args.c
diff -u src/usr.bin/indent/args.c:1.84 src/usr.bin/indent/args.c:1.85
--- src/usr.bin/indent/args.c:1.84	Wed Jun 14 21:35:01 2023
+++ src/usr.bin/indent/args.c	Thu Jun 15 09:19:06 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: args.c,v 1.84 2023/06/14 21:35:01 rillig Exp $	*/
+/*	$NetBSD: args.c,v 1.85 2023/06/15 09:19:06 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: args.c,v 1.84 2023/06/14 21:35:01 rillig Exp $");
+__RCSID("$NetBSD: args.c,v 1.85 2023/06/15 09:19:06 rillig Exp $");
 
 /* Read options from profile files and from the command line. */
 
@@ -68,9 +68,9 @@ __RCSID("$NetBSD: args.c,v 1.84 2023/06/
 /* See set_special_option for special options. */
 static const struct pro {
 	const char p_name[5];	/* e.g. "bl", "cli" */
-	bool p_is_bool;
-	bool p_may_negate;
-	bool p_bool_value;	/* only relevant if !p_may_negate */
+	bool p_is_bool:1;
+	bool p_may_negate:1;
+	bool p_bool_value:1;	/* only relevant if !p_may_negate */
 	short i_min;
 	short i_max;
 	unsigned short opt_offset;	/* the associated variable */

Index: src/usr.bin/indent/indent.c
diff -u src/usr.bin/indent/indent.c:1.368 src/usr.bin/indent/indent.c:1.369
--- src/usr.bin/indent/indent.c:1.368	Thu Jun 15 08:40:20 2023
+++ src/usr.bin/indent/indent.c	Thu Jun 15 09:19:06 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: indent.c,v 1.368 2023/06/15 08:40:20 rillig Exp $	*/
+/*	$NetBSD: indent.c,v 1.369 2023/06/15 09:19:06 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: indent.c,v 1.368 2023/06/15 08:40:20 rillig Exp $");
+__RCSID("$NetBSD: indent.c,v 1.369 2023/06/15 09:19:06 rillig Exp $");
 
 #include <sys/param.h>
 #include <err.h>
@@ -728,10 +728,8 @@ process_lbrace(void)
 			ps.decl_level--;
 		}
 	} else {
-		ps.line_has_decl = false;	/* we can't be in the middle of
-						 * a declaration, so don't do
-						 * special indentation of
-						 * comments */
+		ps.line_has_decl = false;	/* don't do special indentation
+						 * of comments */
 		ps.in_func_def_params = false;
 		ps.in_decl = false;
 	}
@@ -802,7 +800,6 @@ process_unary_op(void)
 	if (is_function_pointer_declaration()) {
 		int ind = ps.decl_ind - (int)token.len;
 		indent_declarator(ind, ps.tabs_to_var);
-		ps.want_blank = false;
 	} else if ((token.s[0] == '+' || token.s[0] == '-')
 	    && code.len > 0 && code.s[code.len - 1] == token.s[0])
 		ps.want_blank = true;
@@ -826,8 +823,8 @@ process_comma(void)
 	ps.want_blank = code.len > 0;	/* only put blank after comma if comma
 					 * does not start the line */
 
-	if (ps.in_decl && !ps.line_has_func_def && !ps.in_init &&
-	    !ps.decl_indent_done && ps.ind_paren_level == 0) {
+	if (ps.in_decl && ps.ind_paren_level == 0
+	    && !ps.line_has_func_def && !ps.in_init && !ps.decl_indent_done) {
 		/* indent leading commas and not the actual identifiers */
 		indent_declarator(ps.decl_ind - 1, ps.tabs_to_var);
 	}
@@ -893,9 +890,6 @@ process_semicolon(void)
 					 * aren't anymore */
 
 	if (ps.paren.len > 0 && ps.spaced_expr_psym != psym_for_exprs) {
-		/* There were unbalanced parentheses in the statement. It is a
-		 * bit complicated, because the semicolon might be in a for
-		 * statement. */
 		diag(1, "Unbalanced parentheses");
 		ps.paren.len = 0;
 		if (ps.spaced_expr_psym != psym_0) {
@@ -929,16 +923,19 @@ process_type_outside_parentheses(void)
 	}
 
 	ps.in_var_decl = /* maybe */ true;
-	ps.in_decl = ps.line_has_decl = ps.prev_lsym != lsym_typedef;
-	if (ps.decl_level <= 0)
+	ps.in_decl = ps.prev_lsym != lsym_typedef;
+	ps.line_has_decl = ps.in_decl;
+	if (ps.decl_level == 0)
 		ps.declaration = decl_begin;
 
-	int len = (code.len > 0 ? ind_add(0, code.s, code.len) + 1 : 0)
-	    + (int)token.len + 1;
 	int ind = ps.ind_level > 0 && ps.decl_level == 0
 	    ? opt.local_decl_indent	/* local variable */
 	    : opt.decl_indent;	/* global variable, or member */
-	ps.decl_ind = ind > 0 ? ind : len;
+	if (ind == 0) {
+		int ind0 = code.len > 0 ? ind_add(0, code.s, code.len) + 1 : 0;
+		ps.decl_ind = ind_add(ind0, token.s, token.len) + 1;
+	} else
+		ps.decl_ind = ind;
 	ps.tabs_to_var = opt.use_tabs && ind > 0;
 }
 
@@ -960,15 +957,14 @@ process_word(lexer_symbol lsym)
 			    && code.len > 0 && code.s[code.len - 1] == '}')
 				ps.decl_ind = ind_add(0, code.s, code.len) + 1;
 			indent_declarator(ps.decl_ind, ps.tabs_to_var);
-			ps.want_blank = false;
 		}
 
 	} else if (ps.spaced_expr_psym != psym_0 && ps.paren.len == 0) {
+		parse(ps.spaced_expr_psym);
+		ps.spaced_expr_psym = psym_0;
 		ps.want_newline = true;
 		ps.in_stmt_or_decl = false;
 		ps.next_unary = true;
-		parse(ps.spaced_expr_psym);
-		ps.spaced_expr_psym = psym_0;
 	}
 }
 
@@ -981,21 +977,22 @@ process_do(void)
 	if (code.len > 0)
 		output_line();
 
-	ps.want_newline = true;
 	parse(psym_do);
+	ps.want_newline = true;
 }
 
 static void
 process_else(void)
 {
 	ps.in_stmt_or_decl = false;
+	ps.in_decl = false;
 
 	if (code.len > 0
 	    && !(opt.cuddle_else && code.s[code.len - 1] == '}'))
 		output_line();
 
-	ps.want_newline = true;
 	parse(psym_else);
+	ps.want_newline = true;
 }
 
 static void
@@ -1079,15 +1076,15 @@ indent(void)
 		if (lsym == lsym_eof)
 			return process_eof();
 
-		if (lsym == lsym_if && ps.prev_lsym == lsym_else
-		    && opt.else_if_in_same_line)
-			ps.want_newline = false;
-
 		if (lsym == lsym_preprocessing || lsym == lsym_newline)
 			ps.want_newline = false;
 		else if (lsym == lsym_comment) {
 			/* no special processing */
 		} else {
+			if (lsym == lsym_if && ps.prev_lsym == lsym_else
+			    && opt.else_if_in_same_line)
+				ps.want_newline = false;
+
 			if (ps.want_newline && should_break_line(lsym)) {
 				ps.want_newline = false;
 				output_line();

Index: src/usr.bin/indent/io.c
diff -u src/usr.bin/indent/io.c:1.221 src/usr.bin/indent/io.c:1.222
--- src/usr.bin/indent/io.c:1.221	Wed Jun 14 16:14:30 2023
+++ src/usr.bin/indent/io.c	Thu Jun 15 09:19:06 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: io.c,v 1.221 2023/06/14 16:14:30 rillig Exp $	*/
+/*	$NetBSD: io.c,v 1.222 2023/06/15 09:19:06 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: io.c,v 1.221 2023/06/14 16:14:30 rillig Exp $");
+__RCSID("$NetBSD: io.c,v 1.222 2023/06/15 09:19:06 rillig Exp $");
 
 #include <stdio.h>
 
@@ -59,12 +59,12 @@ static int paren_indent;
 
 
 static void
-inp_read_next_line(FILE *f)
+inp_read_next_line(void)
 {
 	buf_clear(&inp);
 
 	for (;;) {
-		int ch = getc(f);
+		int ch = getc(input);
 		if (ch == EOF) {
 			if (indent_enabled == indent_on) {
 				buf_add_char(&inp, ' ');
@@ -89,7 +89,7 @@ inp_read_line(void)
 	if (indent_enabled == indent_on)
 		buf_clear(&out.indent_off_text);
 	buf_add_chars(&out.indent_off_text, inp.s, inp.len);
-	inp_read_next_line(input);
+	inp_read_next_line();
 }
 
 void
@@ -208,6 +208,7 @@ compute_case_label_indent(void)
 	while (i > 0 && ps.psyms.sym[i] != psym_switch_expr)
 		i--;
 	float case_ind = (float)ps.psyms.ind_level[i] + opt.case_indent;
+	// TODO: case_ind may become negative here.
 	return (int)(case_ind * (float)opt.indent_size);
 }
 
@@ -218,6 +219,7 @@ compute_label_indent(void)
 		return compute_case_label_indent();
 	if (lab.s[0] == '#')
 		return 0;
+	// TODO: the indentation may become negative here.
 	return opt.indent_size * (ps.ind_level - 2);
 }
 
@@ -235,7 +237,7 @@ compute_lined_up_code_indent(int base_in
 	int overflow = ind_add(ind, code.s, code.len) - opt.max_line_length;
 	if (overflow >= 0
 	    && ind_add(base_ind, code.s, code.len) < opt.max_line_length) {
-		ind -= overflow + 2;
+		ind -= 2 + overflow;
 		if (ind < base_ind)
 			ind = base_ind;
 	}

Reply via email to