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 15b55a22fa1 tools/nxstyle: require a blank line after a function's 
declarations
15b55a22fa1 is described below

commit 15b55a22fa136473afb7eb3b3b54accb2a450fc5
Author: raiden00pl <[email protected]>
AuthorDate: Mon Jul 27 12:20:13 2026 +0200

    tools/nxstyle: require a blank line after a function's declarations
    
    The standard asks for a blank line between the local declarations at the
    head of a function and the code.  A declaration is recognised by its
    shape, since no list of type names can be complete.
    
    Signed-off-by: raiden00pl <[email protected]>
    Assisted-by: Claude Code
---
 tools/nxstyle.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 133 insertions(+), 7 deletions(-)

diff --git a/tools/nxstyle.c b/tools/nxstyle.c
index 1f9a8e80786..a4671e79add 100644
--- a/tools/nxstyle.c
+++ b/tools/nxstyle.c
@@ -1403,6 +1403,107 @@ static bool check_keyword(const char *line, int ndx, 
const char *kw)
   return isalnum((int)line[ndx + len]) == 0 && line[ndx + len] != '_';
 }
 
+/********************************************************************************
+ * Name: check_declaration
+ *
+ * Description:
+ *   Return true if the line has the shape of a declaration: two or more names
+ *   in a row, ending in '=', ';', '[', ',' or a parameter list.  No list of
+ *   type names can be complete, so the shape is used instead.
+ *
+ 
********************************************************************************/
+
+static bool check_declaration(const char *line, int ndx)
+{
+  static const char *const nondecl[] =
+  {
+    "return", "if", "else", "while", "for", "do", "switch", "case",
+    "default", "break", "continue", "goto", "sizeof", "asm", "__asm",
+    "__asm__", NULL
+  };
+
+  const char *const *kw;
+  int nident = 0;
+  int i = ndx;
+
+  /* Must open with a type name; keeps out '*ptr = x;' and comment lines */
+
+  if (isalpha((int)line[ndx]) == 0 && line[ndx] != '_')
+    {
+      return false;
+    }
+
+  for (kw = nondecl; *kw != NULL; kw++)
+    {
+      if (check_keyword(line, ndx, *kw))
+        {
+          return false;
+        }
+    }
+
+  while (line[i] != '\0' && line[i] != '\n')
+    {
+      if (isalpha((int)line[i]) != 0 || line[i] == '_')
+        {
+          nident++;
+          while (isalnum((int)line[i]) != 0 || line[i] == '_')
+            {
+              i++;
+            }
+        }
+      else if (line[i] == ' ' || line[i] == '*')
+        {
+          i++;
+        }
+      else
+        {
+          /* Only a terminator that can follow the declared name counts */
+
+          /* '<type> (*<name>)(...)' declares a pointer to a function.  The
+           * second parameter list tells it from a call like 'foo(*ptr)'.
+           */
+
+          if (line[i] == '(' && nident == 1)
+            {
+              int j = i + 1;
+
+              while (line[j] == ' ')
+                {
+                  j++;
+                }
+
+              if (line[j] == '*')
+                {
+                  j++;
+                  while (line[j] == ' ')
+                    {
+                      j++;
+                    }
+
+                  while (isalnum((int)line[j]) != 0 || line[j] == '_')
+                    {
+                      j++;
+                    }
+
+                  while (line[j] == ' ')
+                    {
+                      j++;
+                    }
+
+                  if (line[j] == ')' && line[j + 1] == '(')
+                    {
+                      return true;
+                    }
+                }
+            }
+
+          return nident >= 2 && strchr("=;[(,", line[i]) != NULL;
+        }
+    }
+
+  return false;
+}
+
 
/********************************************************************************
  * Public Functions
  
********************************************************************************/
@@ -1466,7 +1567,10 @@ int main(int argc, char **argv, char **envp)
   int externc_lineno;   /* Last line where 'extern "C"' declared */
   bool bexact;          /* True: The expected indentation below is exact */
   bool bppline;         /* True: This line is a pre-processor line */
+  bool bdeclline;       /* True: This line begins a local declaration */
   bool blabelline;      /* True: This line holds nothing but a label */
+  bool bindecl;         /* True: A local declaration is being continued */
+  int decl_lineno;      /* Line on which the last declaration ended */
   bool bstmtstart;      /* True: A new statement begins on this line */
   bool bprevstmtend;    /* True: The preceding line of code ended a statement 
*/
   bool bctrlline;       /* True: A control statement starts on this line */
@@ -1598,7 +1702,10 @@ int main(int argc, char **argv, char **envp)
   brace_indent   = 0;           /* Indentation of the awaiting keyword */
   bexact         = false;       /* True: Expected indentation is exact */
   bppline        = false;       /* True: This line is a pre-processor line */
+  bdeclline      = false;       /* True: This line begins a declaration */
   blabelline     = false;       /* True: This line holds nothing but a label */
+  bindecl        = false;       /* True: A declaration is being continued */
+  decl_lineno    = -1;          /* Line on which a declaration last ended */
   bstmtstart     = true;        /* True: A statement begins on this line */
   bprevstmtend   = true;        /* True: The preceding code ended a statement 
*/
   bctrlline      = false;       /* True: A control statement starts here */
@@ -1654,6 +1761,7 @@ int main(int argc, char **argv, char **envp)
       bctrlline    = false;    /* No control statement starts on this line */
       ctrl_bswitch = false;    /* That brace does not open a switch body */
       bppline      = false;    /* True: This line is a pre-processor line */
+      bdeclline    = false;    /* True: This line begins a declaration */
 
       /* A label ends the preceding statement, like a 'case' does */
 
@@ -2285,7 +2393,6 @@ int main(int argc, char **argv, char **envp)
         }
 
       /* Check for some kind of declaration.
-       * REVISIT: The following logic fails for any non-standard types.
        * REVISIT: Terminator after keyword might not be a space.  Might be
        * a newline, for example.  struct and unions are often unnamed, for
        * example.
@@ -2293,6 +2400,16 @@ int main(int argc, char **argv, char **envp)
 
       else if (inasm == 0)
         {
+          /* Note a local declaration, for the blank line that must follow */
+
+          if (bfunctions && bnest > 0 && pnest == 0 && dnest == 0 &&
+              ncomment == 0 && prevncomment == 0 && !bstring && bstmtstart &&
+              check_declaration(line, indent))
+            {
+              bdeclline = true;
+              bindecl   = true;
+            }
+
           if (check_type_name(line, indent) ||
                    strncmp(&line[indent], "auto ", 5) == 0 ||
                    strncmp(&line[indent], "bool ", 5) == 0 ||
@@ -3881,12 +3998,21 @@ int main(int argc, char **argv, char **envp)
                           (lastcode == ':' && (bcaseline || blabelline)));
         }
 
-      /* A line that follows one ending in ';', '{', '}' or ':' begins a new
-       * statement.  Anything else is the continuation of the statement on the
-       * preceding line and may be aligned freely.  Pre-processor lines are
-       * ignored so that a macro definition does not hide the statement that
-       * precedes it.
-       */
+      /* Remember the line on which the last declaration ended */
+
+      if (bindecl && lastcode == ';' && pnest == 0)
+        {
+          decl_lineno = lineno;
+          bindecl     = false;
+        }
+
+      /* A blank line must separate the declarations from the code */
+
+      if (bexact && prevdnest == 0 && !bppline && !bdeclline && !bindecl &&
+          bstmtstart && lineno == decl_lineno + 1 && lastcode != '\0')
+        {
+          ERROR("Missing blank line after declarations", lineno, indent);
+        }
 
       /* STEP 4: Check alignment */
 

Reply via email to