Module Name:    src
Committed By:   rillig
Date:           Thu Nov 25 17:10:53 UTC 2021

Modified Files:
        src/tests/usr.bin/indent: fmt_decl.c indent_off_on.c
        src/usr.bin/indent: lexi.c

Log Message:
indent: fix heuristic for declaration/definition to post-1990 reality


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/tests/usr.bin/indent/fmt_decl.c
cvs rdiff -u -r1.5 -r1.6 src/tests/usr.bin/indent/indent_off_on.c
cvs rdiff -u -r1.157 -r1.158 src/usr.bin/indent/lexi.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.26 src/tests/usr.bin/indent/fmt_decl.c:1.27
--- src/tests/usr.bin/indent/fmt_decl.c:1.26	Thu Nov 25 16:41:33 2021
+++ src/tests/usr.bin/indent/fmt_decl.c	Thu Nov 25 17:10:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: fmt_decl.c,v 1.26 2021/11/25 16:41:33 rillig Exp $	*/
+/*	$NetBSD: fmt_decl.c,v 1.27 2021/11/25 17:10:53 rillig Exp $	*/
 /* $FreeBSD: head/usr.bin/indent/tests/declarations.0 334478 2018-06-01 09:41:15Z pstef $ */
 
 /*
@@ -726,8 +726,13 @@ static Shell	shells[] = {
 
 
 /*
- * Indent gets easily confused by function attribute macros that follow the
- * function declaration.
+ * Before lexi.c 1.158 from 2021-11-25, indent easily got confused by function
+ * attribute macros that followed the function declaration. Its primitive
+ * heuristic between deciding between a function declaration and a function
+ * definition only looked for ')' immediately followed by ',' or ';'. This was
+ * sufficient for well-formatted code before 1990. With the addition of
+ * function prototypes and GCC attributes, the situation became more
+ * complicated, and it took indent 31 years to adapt to this new reality.
  */
 #indent input
 static void JobInterrupt(bool, int) MAKE_ATTR_DEAD;
@@ -735,17 +740,16 @@ static void JobRestartJobs(void);
 #indent end
 
 #indent run
-/* $ FIXME: This is a declaration, not a definition, thus no line break before the name. */
 /* $ FIXME: Missing space before 'MAKE_ATTR_DEAD'. */
-static void
-JobInterrupt(bool, int)MAKE_ATTR_DEAD;
-/* $ FIXME: Must not be indented. */
-	static void	JobRestartJobs(void);
+static void	JobInterrupt(bool, int)MAKE_ATTR_DEAD;
+static void	JobRestartJobs(void);
 #indent end
 
 
 /*
- * Indent gets easily confused by function modifier macros.
+ * Before lexi.c 1.158 from 2021-11-25, indent easily got confused by the
+ * tokens ')' and ';' in the function body. It wrongly regarded them as
+ * finishing a function declaration.
  */
 #indent input
 MAKE_INLINE const char *
@@ -755,22 +759,19 @@ GNode_VarTarget(GNode *gn) { return GNod
 /*
  * Before lexi.c 1.156 from 2021-11-25, indent generated 'GNode * gn' with an
  * extra space.
+ *
+ * Before lexi.c 1.158 from 2021-11-25, indent wrongly placed the function
+ * name in line 1, together with the '{'.
  */
-/* FIXME: The function name must be in column 1 of a separate line. */
-/* FIXME: The '{' must be in column 1 of the next line. */
-/* FIXME: The indentation depends on the function body; try 'return 0'. */
 #indent run
-MAKE_INLINE const char *GNode_VarTarget(GNode *gn) {
+MAKE_INLINE const char *
+GNode_VarTarget(GNode *gn)
+{
 	return GNode_ValueDirect(gn, TARGET);
 }
 #indent end
 
-/* FIXME: Missing space between '*' and 'gn'. */
-#indent run -TGNode
-MAKE_INLINE const char *GNode_VarTarget(GNode *gn){
-	return GNode_ValueDirect(gn, TARGET);
-}
-#indent end
+#indent run-equals-prev-output -TGNode
 
 
 /*

Index: src/tests/usr.bin/indent/indent_off_on.c
diff -u src/tests/usr.bin/indent/indent_off_on.c:1.5 src/tests/usr.bin/indent/indent_off_on.c:1.6
--- src/tests/usr.bin/indent/indent_off_on.c:1.5	Sat Nov 20 11:13:18 2021
+++ src/tests/usr.bin/indent/indent_off_on.c	Thu Nov 25 17:10:53 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: indent_off_on.c,v 1.5 2021/11/20 11:13:18 rillig Exp $ */
+/* $NetBSD: indent_off_on.c,v 1.6 2021/11/25 17:10:53 rillig Exp $ */
 /* $FreeBSD$ */
 
 /*
@@ -189,14 +189,12 @@ void indent_off ( void ) ;
 /* $ XXX: space even though the comment might be regarded to be still in */
 /* $ XXX: the OFF section. */
 /* INDENT */
-void
-indent_on(void);
+void		indent_on(void);
 /* INDENT OFF */
 void indent_off ( void ) ;
 /* $ XXX: The below comment got moved from column 9 to column 1. */
 /* INDENT ON */
-void
-indent_on(void);		/* the comment may be indented */
+void		indent_on(void);	/* the comment may be indented */
 /* INDENT		OFF					*/
 void indent_off ( void ) ;
 /* INDENTATION ON */
@@ -204,16 +202,14 @@ void indent_still_off ( void ) ;	/* due 
 /* INDENT ON * */
 void indent_still_off ( void ) ;	/* due to the extra '*' at the end */
 /* INDENT ON */
-void
-indent_on(void);
+void		indent_on(void);
 /* INDENT: OFF */
-void
-indent_still_on(void);		/* due to the colon in the middle */
+void		indent_still_on(void);	/* due to the colon in the middle */
 /* $ The extra comment got moved to the left since there is no code in */
 /* $ that line. */
 /* INDENT OFF *//* extra comment */
-void
-indent_still_on(void);		/* due to the extra comment to the right */
+void		indent_still_on(void);	/* due to the extra comment to the
+					 * right */
 #indent end
 
 

Index: src/usr.bin/indent/lexi.c
diff -u src/usr.bin/indent/lexi.c:1.157 src/usr.bin/indent/lexi.c:1.158
--- src/usr.bin/indent/lexi.c:1.157	Thu Nov 25 16:51:24 2021
+++ src/usr.bin/indent/lexi.c	Thu Nov 25 17:10:53 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: lexi.c,v 1.157 2021/11/25 16:51:24 rillig Exp $	*/
+/*	$NetBSD: lexi.c,v 1.158 2021/11/25 17:10:53 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -43,7 +43,7 @@ static char sccsid[] = "@(#)lexi.c	8.1 (
 
 #include <sys/cdefs.h>
 #if defined(__NetBSD__)
-__RCSID("$NetBSD: lexi.c,v 1.157 2021/11/25 16:51:24 rillig Exp $");
+__RCSID("$NetBSD: lexi.c,v 1.158 2021/11/25 17:10:53 rillig Exp $");
 #elif defined(__FreeBSD__)
 __FBSDID("$FreeBSD: head/usr.bin/indent/lexi.c 337862 2018-08-15 18:19:45Z pstef $");
 #endif
@@ -453,9 +453,29 @@ cmp_keyword_by_name(const void *key, con
 static bool
 probably_looking_at_definition(void)
 {
-    for (const char *p = inp_p(), *e = inp_line_end(); p < e;)
-	if (*p++ == ')' && (*p == ';' || *p == ','))
-	    return false;
+    int paren_level = 0;
+    for (const char *p = inp_p(), *e = inp_line_end(); p < e; p++) {
+proceed:
+	if (*p == '(')
+	    paren_level++;
+	if (*p == ')' && --paren_level == 0) {
+	    p++;
+	    while (p < e && (ch_isspace(*p) || is_identifier_part(*p)))
+		p++;
+	    if (*p == '(')
+		goto proceed;
+	    return !(*p == ';' || *p == ',');
+	}
+    }
+
+    /*
+     * To further reduce the cases where indent wrongly treats an incomplete
+     * function declaration as a function definition, thus adding a newline
+     * before the function name, it may be worth looking for parameter names,
+     * as these are often omitted in function declarations and only included
+     * in function definitions. Or just increase the lookahead to more than
+     * just the current line of input, until the next '{'.
+     */
     return true;
 }
 

Reply via email to