tools/nxstyle.c: Beef up logic that detects multiple variable definitions per line.

This commit is contained in:
Gregory Nutt 2019-02-17 10:57:28 -06:00
parent af75330012
commit bc5908d9fd
4 changed files with 149 additions and 47 deletions

View File

@ -24,6 +24,16 @@ Status
2019-02-12: A little progress. I do make it all the way into NSH, but
with no console input.
2019-02-13: NSH is now fully functional.
2019-02-17: My plan was to include develop an IEEE 802.15.4 driver
using the interface code for the Cortex-M0 co-processor. Unfortunately,
that interface code is a part of the TI153STACK. The source for that
stack is included in the SDK. However, it looks like the licensing on
that code will prevent that (it is not BSD compatible). That is a shame;
I only want the Cortex-M0 interface, not TI's stack (NuttX has its own
IEEE 802.15.4 stack).
NOTE: This does not prevent you as an end-user from using the TI154STACK;
it only prevents me from re-distributing any part of it.
Serial Console
==============

View File

@ -128,6 +128,16 @@ typedef struct bigint_s bigint_t;
* Private Data
****************************************************************************/
/* REVISIT: __dtoa is not thread safe due to thse two global variables.
* Options:
*
* 1. Allocate on stack. g_freelist is rather large, however.. around 275
* bytes (it could be shrunk a little by using stdint types instead of int.
* 2. Semaphore protect the global variables and handle interrupt level
* calls as a special case (perhaps refusing them? Or having a duplicate
* set of variables, one for tasks and one for interrupt usage)
*/
static FAR bigint_t *g_freelist[KMAX + 1];
static FAR bigint_t *g_p5s;

View File

@ -498,11 +498,13 @@ void nx_start(void)
*/
#ifdef CONFIG_SMP
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_NONCANCELABLE |
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL |
TCB_FLAG_NONCANCELABLE |
TCB_FLAG_CPU_LOCKED);
g_idletcb[cpu].cmn.cpu = cpu;
#else
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_NONCANCELABLE);
g_idletcb[cpu].cmn.flags = (TCB_FLAG_TTYPE_KERNEL |
TCB_FLAG_NONCANCELABLE);
#endif
#ifdef CONFIG_SMP
@ -521,7 +523,8 @@ void nx_start(void)
/* Set the IDLE task name */
# ifdef CONFIG_SMP
snprintf(g_idletcb[cpu].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE", cpu);
snprintf(g_idletcb[cpu].cmn.name, CONFIG_TASK_NAME_SIZE, "CPU%d IDLE",
cpu);
# else
strncpy(g_idletcb[cpu].cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE);
g_idletcb[cpu].cmn.name[CONFIG_TASK_NAME_SIZE] = '\0';

View File

@ -79,14 +79,16 @@ int main(int argc, char **argv, char **envp)
bool bstring; /* True: Within a string */
bool bquote; /* True: Backslash quoted character next */
bool bblank; /* Used to verify block comment termintor */
bool ppline; /* True: The next line the continuation of a precessor command */
int lineno; /* Current line number */
int indent; /* Indentation level */
int ncomment; /* Comment nesting level on this line */
int prevncomment; /* Comment nesting level on the previous line */
int nnest; /* Brace nesting level on this line */
int prevnest; /* Brace nesting level on the previous line */
int declnest; /* Data declaration nesting level on this line */
int prevdeclnest; /* Data declaration nesting level on the previous line */
int bnest; /* Brace nesting level on this line */
int prevbnest; /* Brace nesting level on the previous line */
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 comment_lineno; /* Line on which the last one line 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 */
@ -143,10 +145,12 @@ int main(int argc, char **argv, char **envp)
bfunctions = false; /* True: In private or public functions */
bswitch = false; /* True: Within a switch statement */
bstring = false; /* True: Within a string */
ppline = false; /* True: Continuation of a pre-processor line */
lineno = 0; /* Current line number */
ncomment = 0; /* Comment nesting level on this line */
nnest = 0; /* Brace nesting level on this line */
declnest = 0; /* Data declaration nesting level on this line */
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 */
comment_lineno = -1; /* Line on which the last one line 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 */
@ -155,8 +159,8 @@ int main(int argc, char **argv, char **envp)
{
lineno++;
indent = 0;
prevnest = nnest; /* Brace nesting level on the previous line */
prevdeclnest = declnest; /* Data declaration nesting level on the previous line */
prevbnest = bnest; /* Brace nesting level on the previous line */
prevdnest = dnest; /* Data declaration nesting level on the previous line */
prevncomment = ncomment; /* Comment nesting level on the previous line */
bstatm = false; /* True: This line is beginning of a statement */
bfor = false; /* REVISIT: Implies for() is all on one line */
@ -259,13 +263,29 @@ int main(int argc, char **argv, char **envp)
}
/* STEP 2: Detect some certain start of line conditions */
/* Skip over pre-processor lines */
/* Skip over pre-processor lines (or continuations of pre-processor
* lines as indicated by ppline)
*/
if (line[indent] == '#')
if (line[indent] == '#' || ppline)
{
int len;
/* Suppress error for comment following conditional compilation */
noblank_lineno = lineno;
/* Check if the next line will be a continuation of the pre-
* processor command.
*/
len = strlen(&line[indent]) + indent - 1;
if (line[len] == '\n')
{
len--;
}
ppline = (line[len] == '\\');
continue;
}
@ -351,22 +371,62 @@ int main(int argc, char **argv, char **envp)
/* REVISIT: Also picks up function return types */
/* REVISIT: Logic problem for nested data/function declarations */
if ((!bfunctions || nnest > 0) && declnest == 0)
if ((!bfunctions || bnest > 0) && dnest == 0)
{
declnest = 1;
dnest = 1;
}
/* Check for multiple definitions of local variables on the line.
* NOTE: Will miss multiple global variable definitions on a line,
* but this is because the heuristic is not smart enough to
* distingush a global variable from a function prototype.
/* Check for multiple definitions of variables on the line.
* Ignores declarations within parentheses which are probably
* formal parameters.
*/
if (indent > 0 && strchr(&line[indent], ',') != NULL)
if (pnest == 0)
{
fprintf(stderr,
"Multiple data definitions on line %d\n",
lineno);
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++)
{
if (tmppnest == 0 && line[i] == ',')
{
fprintf(stderr,
"Multiple data definitions on line %d\n",
lineno);
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;
}
}
}
}
@ -592,7 +652,7 @@ int main(int argc, char **argv, char **envp)
{
if (n > indent)
{
if (declnest == 0)
if (dnest == 0)
{
fprintf(stderr,
"Left bracket not on separate line at %d:%d\n",
@ -601,7 +661,7 @@ int main(int argc, char **argv, char **envp)
}
else if (line[n + 1] != '\n')
{
if (declnest == 0)
if (dnest == 0)
{
fprintf(stderr,
"Garbage follows left bracket at line %d:%d\n",
@ -609,10 +669,10 @@ int main(int argc, char **argv, char **envp)
}
}
nnest++;
if (declnest > 0)
bnest++;
if (dnest > 0)
{
declnest++;
dnest++;
}
/* Suppress error for comment following a left brace */
@ -623,32 +683,32 @@ int main(int argc, char **argv, char **envp)
case '}':
{
if (nnest < 1)
if (bnest < 1)
{
fprintf(stderr, "Unmatched right brace at line %d:%d\n", lineno, n);
}
else
{
nnest--;
if (nnest < 1)
bnest--;
if (bnest < 1)
{
nnest = 0;
bnest = 0;
bswitch = false;
}
}
if (declnest < 3)
if (dnest < 3)
{
declnest = 0;
dnest = 0;
}
else
{
declnest--;
dnest--;
}
if (n > indent)
{
if (declnest == 0)
if (dnest == 0)
{
fprintf(stderr,
"Right bracket not on separate line at %d:%d\n",
@ -665,7 +725,7 @@ int main(int argc, char **argv, char **envp)
* structure.
*/
if (prevdeclnest <= 0 || declnest > 0)
if (prevdnest <= 0 || dnest > 0)
{
/* REVISIT: Generates false alarms on named structures
* that are fields of other structures or unions.
@ -679,10 +739,16 @@ int main(int argc, char **argv, char **envp)
}
break;
/* Check for inappropriate space around parentheses */
/* Handle logic with parenthese */
case '(':
{
/* Increase the parenthetical nesting level */
pnest++;
/* Check for inappropriate space around parentheses */
if (line[n + 1] == ' ' /* && !bfor */)
{
fprintf(stderr,
@ -694,6 +760,19 @@ int main(int argc, char **argv, char **envp)
case ')':
{
/* Decrease the parenthetical nesting level */
if (pnest < 1)
{
fprintf(stderr, "Unmatched right parentheses at line %d:%d\n",
lineno, n);
pnest = 0;
}
else
{
pnest--;
}
/* Allow ')' as first thing on the line (n == indent)
* Allow "for (xx; xx; )" (bfor == true)
*/
@ -742,12 +821,12 @@ int main(int argc, char **argv, char **envp)
}
/* Semicolon terminates a declaration/definition if there
* was no left curly brace (i.e., declnest is only 1).
* was no left curly brace (i.e., dnest is only 1).
*/
if (declnest == 1)
if (dnest == 1)
{
declnest = 0;
dnest = 0;
}
}
break;
@ -1050,7 +1129,7 @@ int main(int argc, char **argv, char **envp)
}
else if (indent > 0 && indent < 2)
{
if (nnest > 0)
if (bnest > 0)
{
fprintf(stderr, "Insufficient indentation line %d:%d\n",
lineno, indent);
@ -1091,7 +1170,7 @@ int main(int argc, char **argv, char **envp)
* comments before beginning of function definitions.
*/
if ((indent & 3) != 3 && bfunctions && declnest == 0)
if ((indent & 3) != 3 && bfunctions && dnest == 0)
{
fprintf(stderr,
"Bad comment block alignment at line %d:%d\n",
@ -1128,7 +1207,7 @@ int main(int argc, char **argv, char **envp)
{
/* Ignore if we are at global scope */
if (prevnest > 0)
if (prevbnest > 0)
{
bool blabel = false;
@ -1163,7 +1242,7 @@ int main(int argc, char **argv, char **envp)
{
/* REVISIT: False alarms in data initializers and switch statements */
if ((indent & 3) != 0 && !bswitch && declnest == 0)
if ((indent & 3) != 0 && !bswitch && dnest == 0)
{
fprintf(stderr, "Bad left brace alignment at line %d:%d\n",
lineno, indent);
@ -1173,7 +1252,7 @@ int main(int argc, char **argv, char **envp)
{
/* REVISIT: False alarms in data initializers and switch statements */
if ((indent & 3) != 0 && !bswitch && prevdeclnest == 0)
if ((indent & 3) != 0 && !bswitch && prevdnest == 0)
{
fprintf(stderr, "Bad right brace alignment at line %d:%d\n",
lineno, indent);
@ -1195,7 +1274,7 @@ int main(int argc, char **argv, char **envp)
if ((bstatm || /* Begins with C keyword */
(line[indent] == '/' && bfunctions)) && /* Comment in functions */
!bswitch && /* Not in a switch */
declnest == 0) /* Not a data definition */
dnest == 0) /* Not a data definition */
{
if ((indent & 3) != 2)
{