mirror of
https://github.com/apache/nuttx.git
synced 2026-08-12 16:06:51 +00:00
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 <raiden00@railab.me> Assisted-by: Claude Code
This commit is contained in:
parent
7fc26fd50c
commit
ea2f8e5cbf
1 changed files with 166 additions and 0 deletions
166
tools/nxstyle.c
166
tools/nxstyle.c
|
|
@ -1340,6 +1340,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
|
||||
********************************************************************************/
|
||||
|
|
@ -1363,6 +1384,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
|
||||
|
|
@ -1501,6 +1527,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 */
|
||||
|
|
@ -1535,6 +1566,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.
|
||||
|
|
@ -1817,6 +1851,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;
|
||||
|
|
@ -2305,6 +2341,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 */
|
||||
|
|
@ -2926,6 +3016,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;
|
||||
|
||||
|
|
@ -3474,6 +3571,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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue