From cdf615855ac3bd0f3283dc87a414e4d8cb6f49e9 Mon Sep 17 00:00:00 2001 From: Johanne Schock Date: Sat, 14 Mar 2020 14:36:47 +0100 Subject: [PATCH] Added assembly header detection. --- tools/nxstyle.c | 503 ++++++++++++++++++++++++++++-------------------- 1 file changed, 296 insertions(+), 207 deletions(-) diff --git a/tools/nxstyle.c b/tools/nxstyle.c index da536f82f5..bcd7d6d017 100644 --- a/tools/nxstyle.c +++ b/tools/nxstyle.c @@ -116,6 +116,10 @@ enum pptype_e { PPLINE_NONE = 0, PPLINE_DEFINE, + PPLINE_IF, + PPLINE_ELIF, + PPLINE_ELSE, + PPLINE_ENDIF, PPLINE_OTHER }; @@ -526,6 +530,8 @@ int main(int argc, char **argv, char **envp) int dnest; /* Data declaration nesting level on this line */ int prevdnest; /* Data declaration nesting level on the previous line */ int pnest; /* Parenthesis nesting level on this line */ + int ppifnest; /* #if nesting level on this line */ + int inasm; /* > 0: Within #ifdef __ASSEMBLY__ */ int comment_lineno; /* Line on which the last comment was closed */ int blank_lineno; /* Line number of the last blank line */ int noblank_lineno; /* A blank line is not needed after this line */ @@ -643,6 +649,8 @@ int main(int argc, char **argv, char **envp) bnest = 0; /* Brace nesting level on this line */ dnest = 0; /* Data declaration nesting level on this line */ pnest = 0; /* Parenthesis nesting level on this line */ + ppifnest = 0; /* #if nesting level on this line */ + inasm = 0; /* > 0: Within #ifdef __ASSEMBLY__ */ comment_lineno = -1; /* Line on which the last comment was closed */ blank_lineno = -1; /* Line number of the last blank line */ noblank_lineno = -1; /* A blank line is not needed after this line */ @@ -851,71 +859,147 @@ int main(int argc, char **argv, char **envp) * line. */ + ii = indent + 1; + if (ppline == PPLINE_NONE) { /* Skip to the pre-processor command following the '#' */ - for (ii = indent + 1; - line[ii] != '\0' && isspace(line[ii]); - ii++) - { - } + while (line[ii] != '\0' && isspace(line[ii])) + { + ii++; + } - if (line[ii] != '\0') - { - /* Make sure that pre-processor definitions are all in - * the pre-processor definitions section. - */ + if (line[ii] != '\0') + { + /* Make sure that pre-processor definitions are all in + * the pre-processor definitions section. + */ - ppline = PPLINE_OTHER; + ppline = PPLINE_OTHER; - if (strncmp(&line[ii], "define", 6) == 0) - { - ppline = PPLINE_DEFINE; + if (strncmp(&line[ii], "define", 6) == 0) + { + ppline = PPLINE_DEFINE; - if (g_section != PRE_PROCESSOR_DEFINITIONS) - { - /* A complication is the header files always have - * the idempotence guard definitions before the - * "Pre-processor Definitions section". - */ + if (g_section != PRE_PROCESSOR_DEFINITIONS) + { + /* A complication is the header files always have + * the idempotence guard definitions before the + * "Pre-processor Definitions section". + */ - if (g_section == NO_SECTION && - g_file_type != C_HEADER) - { - /* Only a warning because there is some usage - * of define outside the Pre-processor - * Definitions section which is justifiable. - * Should be manually checked. - */ + if (g_section == NO_SECTION && + g_file_type != C_HEADER) + { + /* Only a warning because there is some usage + * of define outside the Pre-processor + * Definitions section which is justifiable. + * Should be manually checked. + */ - WARN("#define outside of 'Pre-processor " - "Definitions' section", - lineno, ii); - } - } - } + WARN("#define outside of 'Pre-processor " + "Definitions' section", + lineno, ii); + } + } + } - /* Make sure that files are included only in the Included - * Files section. - */ + /* Make sure that files are included only in the Included + * Files section. + */ - else if (strncmp(&line[ii], "include", 7) == 0) - { - if (g_section != INCLUDED_FILES) - { - /* Only a warning because there is some usage of - * include outside the Included Files section - * which may be is justifiable. Should be - * manually checked. - */ + else if (strncmp(&line[ii], "include", 7) == 0) + { + if (g_section != INCLUDED_FILES) + { + /* Only a warning because there is some usage of + * include outside the Included Files section + * which may be is justifiable. Should be + * manually checked. + */ - WARN("#include outside of 'Included Files' " - "section", - lineno, ii); - } - } - } + WARN("#include outside of 'Included Files' " + "section", + lineno, ii); + } + } + else if (strncmp(&line[ii], "if", 2) == 0) + { + ppifnest++; + + ppline = PPLINE_IF; + ii += 2; + } + else if (strncmp(&line[ii], "elif", 4) == 0) + { + if (ppifnest == inasm) + { + inasm = 0; + } + + ppline = PPLINE_ELIF; + ii += 4; + } + else if (strncmp(&line[ii], "else", 4) == 0) + { + if (ppifnest == inasm) + { + inasm = 0; + } + + ppline = PPLINE_ELSE; + } + else if (strncmp(&line[ii], "endif", 4) == 0) + { + if (ppifnest == inasm) + { + inasm = 0; + } + + ppifnest--; + + ppline = PPLINE_ENDIF; + } + } + } + + if (ppline == PPLINE_IF || ppline == PPLINE_ELIF) + { + int bdef = 0; + + if (strncmp(&line[ii], "def", 3) == 0) + { + bdef = 1; + ii += 3; + } + else + { + while (line[ii] != '\0' && isspace(line[ii])) + { + ii++; + } + + if (strncmp(&line[ii], "defined", 7) == 0) + { + bdef = 1; + ii += 7; + } + } + + if (bdef) + { + while (line[ii] != '\0' && + (isspace(line[ii]) || line[ii] == '(')) + { + ii++; + } + + if (strncmp(&line[ii], "__ASSEMBLY__", 12) == 0) + { + inasm = ppifnest; + } + } } /* Check if the next line will be a continuation of the pre- @@ -968,10 +1052,12 @@ int main(int argc, char **argv, char **envp) rhcomment = -1; - if (ncomment > 0 && (strncmp(&line[ii], "if", 2) == 0 || - strncmp(&line[ii], "el", 2) == 0)) + if (ncomment > 0 && + (ppline == PPLINE_IF || + ppline == PPLINE_ELSE || + ppline == PPLINE_ELIF)) { - /* in #if... and #el.. */ + /* in #if... and #el... */ ERROR("No multiline comment right of code allowed here", lineno, n); @@ -1047,175 +1133,178 @@ int main(int argc, char **argv, char **envp) * example. */ - else if (strncmp(&line[indent], "auto ", 5) == 0 || - strncmp(&line[indent], "bool ", 5) == 0 || - strncmp(&line[indent], "char ", 5) == 0 || - strncmp(&line[indent], "CODE ", 5) == 0 || - strncmp(&line[indent], "const ", 6) == 0 || - strncmp(&line[indent], "double ", 7) == 0 || - strncmp(&line[indent], "struct ", 7) == 0 || - strncmp(&line[indent], "struct\n", 7) == 0 || /* May be unnamed */ - strncmp(&line[indent], "enum ", 5) == 0 || - strncmp(&line[indent], "extern ", 7) == 0 || - strncmp(&line[indent], "EXTERN ", 7) == 0 || - strncmp(&line[indent], "FAR ", 4) == 0 || - strncmp(&line[indent], "float ", 6) == 0 || - strncmp(&line[indent], "int ", 4) == 0 || - strncmp(&line[indent], "int16_t ", 8) == 0 || - strncmp(&line[indent], "int32_t ", 8) == 0 || - strncmp(&line[indent], "long ", 5) == 0 || - strncmp(&line[indent], "off_t ", 6) == 0 || - strncmp(&line[indent], "register ", 9) == 0 || - strncmp(&line[indent], "short ", 6) == 0 || - strncmp(&line[indent], "signed ", 7) == 0 || - strncmp(&line[indent], "size_t ", 7) == 0 || - strncmp(&line[indent], "ssize_t ", 8) == 0 || - strncmp(&line[indent], "static ", 7) == 0 || - strncmp(&line[indent], "time_t ", 7) == 0 || - strncmp(&line[indent], "typedef ", 8) == 0 || - strncmp(&line[indent], "uint8_t ", 8) == 0 || - strncmp(&line[indent], "uint16_t ", 9) == 0 || - strncmp(&line[indent], "uint32_t ", 9) == 0 || - strncmp(&line[indent], "union ", 6) == 0 || - strncmp(&line[indent], "union\n", 6) == 0 || /* May be unnamed */ - strncmp(&line[indent], "unsigned ", 9) == 0 || - strncmp(&line[indent], "void ", 5) == 0 || - strncmp(&line[indent], "volatile ", 9) == 0) + else if (inasm == 0) { - /* Check if this is extern "C"; We don't typically indent following - * this. - */ - - if (strncmp(&line[indent], "extern \"C\"", 10) == 0) + if (strncmp(&line[indent], "auto ", 5) == 0 || + strncmp(&line[indent], "bool ", 5) == 0 || + strncmp(&line[indent], "char ", 5) == 0 || + strncmp(&line[indent], "CODE ", 5) == 0 || + strncmp(&line[indent], "const ", 6) == 0 || + strncmp(&line[indent], "double ", 7) == 0 || + strncmp(&line[indent], "struct ", 7) == 0 || + strncmp(&line[indent], "struct\n", 7) == 0 || /* May be unnamed */ + strncmp(&line[indent], "enum ", 5) == 0 || + strncmp(&line[indent], "extern ", 7) == 0 || + strncmp(&line[indent], "EXTERN ", 7) == 0 || + strncmp(&line[indent], "FAR ", 4) == 0 || + strncmp(&line[indent], "float ", 6) == 0 || + strncmp(&line[indent], "int ", 4) == 0 || + strncmp(&line[indent], "int16_t ", 8) == 0 || + strncmp(&line[indent], "int32_t ", 8) == 0 || + strncmp(&line[indent], "long ", 5) == 0 || + strncmp(&line[indent], "off_t ", 6) == 0 || + strncmp(&line[indent], "register ", 9) == 0 || + strncmp(&line[indent], "short ", 6) == 0 || + strncmp(&line[indent], "signed ", 7) == 0 || + strncmp(&line[indent], "size_t ", 7) == 0 || + strncmp(&line[indent], "ssize_t ", 8) == 0 || + strncmp(&line[indent], "static ", 7) == 0 || + strncmp(&line[indent], "time_t ", 7) == 0 || + strncmp(&line[indent], "typedef ", 8) == 0 || + strncmp(&line[indent], "uint8_t ", 8) == 0 || + strncmp(&line[indent], "uint16_t ", 9) == 0 || + strncmp(&line[indent], "uint32_t ", 9) == 0 || + strncmp(&line[indent], "union ", 6) == 0 || + strncmp(&line[indent], "union\n", 6) == 0 || /* May be unnamed */ + strncmp(&line[indent], "unsigned ", 9) == 0 || + strncmp(&line[indent], "void ", 5) == 0 || + strncmp(&line[indent], "volatile ", 9) == 0) { - externc_lineno = lineno; - } - - /* bfunctions: True: Processing private or public functions. - * bnest: Brace nesting level on this line - * dnest: Data declaration nesting level on this line - */ - - /* REVISIT: Also picks up function return types */ - - /* REVISIT: Logic problem for nested data/function declarations */ - - if ((!bfunctions || bnest > 0) && dnest == 0) - { - dnest = 1; - } - - /* Check for multiple definitions of variables on the line. - * Ignores declarations within parentheses which are probably - * formal parameters. - */ - - if (pnest == 0) - { - int tmppnest; - - /* Note, we have not yet parsed each character on the line so - * a comma have have been be preceded by '(' on the same line. - * We will have parse up to any comma to see if that is the - * case. + /* Check if this is extern "C"; We don't typically indent + * following this. */ - for (i = indent, tmppnest = 0; - line[i] != '\n' && line[i] != '\0'; - i++) + if (strncmp(&line[indent], "extern \"C\"", 10) == 0) { - if (tmppnest == 0 && line[i] == ',') + externc_lineno = lineno; + } + + /* bfunctions: True: Processing private or public functions. + * bnest: Brace nesting level on this line + * dnest: Data declaration nesting level on this line + */ + + /* REVISIT: Also picks up function return types */ + + /* REVISIT: Logic problem for nested data/function declarations */ + + if ((!bfunctions || bnest > 0) && dnest == 0) + { + dnest = 1; + } + + /* Check for multiple definitions of variables on the line. + * Ignores declarations within parentheses which are probably + * formal parameters. + */ + + if (pnest == 0) + { + int tmppnest; + + /* Note, we have not yet parsed each character on the line so + * a comma have have been be preceded by '(' on the same line. + * We will have parse up to any comma to see if that is the + * case. + */ + + for (i = indent, tmppnest = 0; + line[i] != '\n' && line[i] != '\0'; + i++) { - ERROR("Multiple data definitions", lineno, i + 1); - break; - } - else if (line[i] == '(') - { - tmppnest++; - } - else if (line[i] == ')') - { - if (tmppnest < 1) + if (tmppnest == 0 && line[i] == ',') { - /* We should catch this later */ + ERROR("Multiple data definitions", lineno, i + 1); + break; + } + else if (line[i] == '(') + { + tmppnest++; + } + else if (line[i] == ')') + { + if (tmppnest < 1) + { + /* We should catch this later */ + + break; + } + + tmppnest--; + } + else if (line[i] == ';') + { + /* Break out if the semicolon terminates the + * declaration is found. Avoids processing any + * righthand comments in most cases. + */ break; } - - tmppnest--; - } - else if (line[i] == ';') - { - /* Break out if the semicolon terminates the - * declaration is found. Avoids processing any - * righthand comments in most cases. - */ - - break; } } } - } - /* Check for a keyword indicating the beginning of a statement. - * REVISIT: This, obviously, will not detect statements that do not - * begin with a C keyword (such as assignment statements). - */ + /* Check for a keyword indicating the beginning of a statement. + * REVISIT: This, obviously, will not detect statements that do not + * begin with a C keyword (such as assignment statements). + */ - else if (strncmp(&line[indent], "break ", 6) == 0 || - strncmp(&line[indent], "case ", 5) == 0 || -#if 0 /* Part of switch */ - strncmp(&line[indent], "case ", 5) == 0 || -#endif - strncmp(&line[indent], "continue ", 9) == 0 || + else if (strncmp(&line[indent], "break ", 6) == 0 || + strncmp(&line[indent], "case ", 5) == 0 || + #if 0 /* Part of switch */ + strncmp(&line[indent], "case ", 5) == 0 || + #endif + strncmp(&line[indent], "continue ", 9) == 0 || -#if 0 /* Part of switch */ - strncmp(&line[indent], "default ", 8) == 0 || -#endif - strncmp(&line[indent], "do ", 3) == 0 || - strncmp(&line[indent], "else ", 5) == 0 || - strncmp(&line[indent], "goto ", 5) == 0 || - strncmp(&line[indent], "if ", 3) == 0 || - strncmp(&line[indent], "return ", 7) == 0 || -#if 0 /* Doesn't follow pattern */ - strncmp(&line[indent], "switch ", 7) == 0 || -#endif - strncmp(&line[indent], "while ", 6) == 0) - { - bstatm = true; - } + #if 0 /* Part of switch */ + strncmp(&line[indent], "default ", 8) == 0 || + #endif + strncmp(&line[indent], "do ", 3) == 0 || + strncmp(&line[indent], "else ", 5) == 0 || + strncmp(&line[indent], "goto ", 5) == 0 || + strncmp(&line[indent], "if ", 3) == 0 || + strncmp(&line[indent], "return ", 7) == 0 || + #if 0 /* Doesn't follow pattern */ + strncmp(&line[indent], "switch ", 7) == 0 || + #endif + strncmp(&line[indent], "while ", 6) == 0) + { + bstatm = true; + } - /* Spacing works a little differently for and switch statements */ + /* Spacing works a little differently for and switch statements */ - else if (strncmp(&line[indent], "for ", 4) == 0) - { - bfor = true; - bstatm = true; - } - else if (strncmp(&line[indent], "switch ", 7) == 0) - { - bswitch = true; - } + else if (strncmp(&line[indent], "for ", 4) == 0) + { + bfor = true; + bstatm = true; + } + else if (strncmp(&line[indent], "switch ", 7) == 0) + { + bswitch = true; + } - /* Also check for C keywords with missing white space */ + /* Also check for C keywords with missing white space */ - else if (strncmp(&line[indent], "do(", 3) == 0 || - strncmp(&line[indent], "if(", 3) == 0 || - strncmp(&line[indent], "while(", 6) == 0) - { - ERROR("Missing whitespace after keyword", lineno, n); - bstatm = true; - } - else if (strncmp(&line[indent], "for(", 4) == 0) - { - ERROR("Missing whitespace after keyword", lineno, n); - bfor = true; - bstatm = true; - } - else if (strncmp(&line[indent], "switch(", 7) == 0) - { - ERROR("Missing whitespace after keyword", lineno, n); - bswitch = true; + else if (strncmp(&line[indent], "do(", 3) == 0 || + strncmp(&line[indent], "if(", 3) == 0 || + strncmp(&line[indent], "while(", 6) == 0) + { + ERROR("Missing whitespace after keyword", lineno, n); + bstatm = true; + } + else if (strncmp(&line[indent], "for(", 4) == 0) + { + ERROR("Missing whitespace after keyword", lineno, n); + bfor = true; + bstatm = true; + } + else if (strncmp(&line[indent], "switch(", 7) == 0) + { + ERROR("Missing whitespace after keyword", lineno, n); + bswitch = true; + } } /* STEP 3: Parse each character on the line */ @@ -1590,14 +1679,14 @@ int main(int argc, char **argv, char **envp) bquote = false; } - /* The reset of the line is only examined of we are not in a comment - * or a string. + /* The rest of the line is only examined of we are not in a comment, + * in a string or in assembly. * * REVISIT: Should still check for whitespace at the end of the * line. */ - if (ncomment == 0 && !bstring) + if (ncomment == 0 && !bstring && inasm == 0) { switch (line[n]) {