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; }