This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 4cf4c5d710f tools/nxstyle: require braces around control statement
bodies
4cf4c5d710f is described below
commit 4cf4c5d710f60d838253a136325547f19256ed12
Author: raiden00pl <[email protected]>
AuthorDate: Mon Jul 27 12:20:12 2026 +0200
tools/nxstyle: require braces around control statement bodies
The standard requires braces after 'if', 'else', 'while', 'for' and 'do'
even when the body is a single statement. Nothing checked this.
Signed-off-by: raiden00pl <[email protected]>
Assisted-by: Claude Code
---
tools/nxstyle.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/tools/nxstyle.c b/tools/nxstyle.c
index 89683934df7..b4d18f774a5 100644
--- a/tools/nxstyle.c
+++ b/tools/nxstyle.c
@@ -1354,6 +1354,27 @@ static bool white_content_list(const char *ident, int
lineno)
return false;
}
+/********************************************************************************
+ * Name: check_keyword
+ *
+ * Description:
+ * Return true if line[ndx] holds the keyword 'kw', delimited by a character
+ * that cannot be part of an identifier.
+ *
+
********************************************************************************/
+
+static bool check_keyword(const char *line, int ndx, const char *kw)
+{
+ size_t len = strlen(kw);
+
+ if (strncmp(&line[ndx], kw, len) != 0)
+ {
+ return false;
+ }
+
+ return isalnum((int)line[ndx + len]) == 0 && line[ndx + len] != '_';
+}
+
/********************************************************************************
* Public Functions
********************************************************************************/
@@ -1377,6 +1398,11 @@ int main(int argc, char **argv, char **envp)
bool bquote; /* True: Backslash quoted character next */
bool bblank; /* Used to verify block comment terminator */
bool bexternc; /* True: Within 'extern "C"' */
+ bool bppline; /* True: This line is a pre-processor line */
+ bool bctrlline; /* True: A control statement starts on this line */
+ const char *ctrl_kw; /* Control keyword whose header is being parsed */
+ const char *brace_kw; /* Control keyword still waiting for its left brace */
+ int ctrl_hdrend; /* Index of the last character of that header */
enum pptype_e ppline; /* > 0: The next line the continuation of a
* pre-processor command */
int rhcomment; /* Indentation of Comment to the right of code
@@ -1515,6 +1541,11 @@ int main(int argc, char **argv, char **envp)
bcase = false; /* True: Within a case statement of a switch */
bstring = false; /* True: Within a string */
bexternc = false; /* True: Within 'extern "C"' */
+ bppline = false; /* True: This line is a pre-processor line */
+ bctrlline = false; /* True: A control statement starts here */
+ ctrl_kw = NULL; /* Control keyword being parsed */
+ brace_kw = NULL; /* Control keyword waiting for a brace */
+ ctrl_hdrend = -1; /* Index of the end of that header */
bif = false; /* True: This line is beginning of a 'if'
statement */
ppline = PPLINE_NONE; /* > 0: The next line the continuation of a
* pre-processor command */
@@ -1549,6 +1580,9 @@ int main(int argc, char **argv, char **envp)
bstatm = false; /* True: This line is beginning of a
* statement */
bfor = false; /* REVISIT: Implies for() is all on one line */
+ bppline = false; /* True: This line is a pre-processor line */
+ bctrlline = false; /* No control statement starts on this line */
+ ctrl_hdrend = -1; /* The header has not ended on this line yet */
/* If we are not in a comment, then this certainly is not a right-hand
* comment.
@@ -1831,6 +1865,8 @@ int main(int argc, char **argv, char **envp)
int len;
int ii;
+ bppline = true;
+
/* Suppress error for comment following conditional compilation */
noblank_lineno = lineno;
@@ -2319,6 +2355,60 @@ int main(int argc, char **argv, char **envp)
bfor = true;
bstatm = true;
}
+
+ /* A control statement whose body must be braced. ctrl_kw stays
+ * set while the condition continues over several lines.
+ */
+
+ if (bnest > 0 && dnest == 0 && ctrl_kw == NULL)
+ {
+ bctrlline = true;
+
+ if (check_keyword(line, indent, "else"))
+ {
+ int ndx = indent + 4;
+
+ while (line[ndx] == ' ')
+ {
+ ndx++;
+ }
+
+ if (check_keyword(line, ndx, "if"))
+ {
+ ctrl_kw = "else if";
+ }
+ else
+ {
+ ctrl_kw = "else";
+ ctrl_hdrend = indent + 3;
+ }
+ }
+ else if (check_keyword(line, indent, "do"))
+ {
+ ctrl_kw = "do";
+ ctrl_hdrend = indent + 1;
+ }
+ else if (check_keyword(line, indent, "if"))
+ {
+ ctrl_kw = "if";
+ }
+ else if (check_keyword(line, indent, "while"))
+ {
+ ctrl_kw = "while";
+ }
+ else if (check_keyword(line, indent, "for"))
+ {
+ ctrl_kw = "for";
+ }
+ else if (check_keyword(line, indent, "switch"))
+ {
+ ctrl_kw = "switch";
+ }
+ else
+ {
+ bctrlline = false;
+ }
+ }
}
/* STEP 3: Parse each character on the line */
@@ -2940,6 +3030,13 @@ int main(int argc, char **argv, char **envp)
{
bif = false;
}
+
+ /* Remember where the header ends, to see what follows */
+
+ if (ctrl_kw != NULL && pnest == 0 && ctrl_hdrend < 0)
+ {
+ ctrl_hdrend = n;
+ }
}
break;
@@ -3488,6 +3585,75 @@ int main(int argc, char **argv, char **envp)
}
}
+ /* STEP 3b: The body of a control statement must be braced, even when
+ * it is a single statement or is empty.
+ */
+
+ if (ncomment == 0 && prevncomment == 0 && !bstring && inasm == 0 &&
+ !bppline)
+ {
+ bool bcommentline = line[indent] == '/' &&
+ (line[indent + 1] == '*' ||
+ line[indent + 1] == '/');
+
+ /* Does this line supply a brace an earlier statement promised?
+ * A comment between the two is tolerated.
+ */
+
+ if (brace_kw != NULL && !bcommentline)
+ {
+ /* A control statement may stand where the brace was expected:
+ * an 'else if', or alternatives sharing the braces that follow.
+ */
+
+ if (line[indent] != '{' && !bctrlline)
+ {
+ snprintf(buffer, sizeof(buffer),
+ "Missing braces after '%s'", brace_kw);
+ ERROR(buffer, lineno, indent);
+ }
+
+ brace_kw = NULL;
+ }
+
+ /* Has the header ended on this line? If so, see what follows */
+
+ if (ctrl_kw != NULL && pnest == 0 && ctrl_hdrend >= 0)
+ {
+ int ndx = ctrl_hdrend + 1;
+
+ while (line[ndx] == ' ' || line[ndx] == '\t')
+ {
+ ndx++;
+ }
+
+ if (line[ndx] == '\n' || line[ndx] == '\0' ||
+ (line[ndx] == '/' &&
+ (line[ndx + 1] == '*' || line[ndx + 1] == '/')))
+ {
+ /* The brace must appear on a following line */
+
+ brace_kw = ctrl_kw;
+ }
+ else if (line[ndx] == ';' &&
+ (strcmp(ctrl_kw, "while") == 0 ||
+ strcmp(ctrl_kw, "for") == 0))
+ {
+ /* A null statement needs no braces; also the 'while' of
+ * a 'do .. while'.
+ */
+ }
+ else
+ {
+ snprintf(buffer, sizeof(buffer),
+ "Statement on same line as '%s'", ctrl_kw);
+ ERROR(buffer, lineno, ndx);
+ }
+
+ ctrl_kw = NULL;
+ }
+ }
+
/* STEP 4: Check alignment */
/* Within a comment block, we need only check on the alignment of the