lint: clean up lex.c
Rename 'struct kwtab' to 'struct keyword' since a single keyword is not a whole keyword table. Sync comment for lex_name with reality: sbuf_t no longer contains the hash value. Remove redundant tests for EOF, as EOF is neither a space nor a digit nor an xdigit. No functional change.
This commit is contained in:
parent
2c1fba9316
commit
94d1e5f09d
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: d_c99_bool_strict_syshdr.c,v 1.10 2021/12/21 16:25:14 rillig Exp $ */
|
||||
/* $NetBSD: d_c99_bool_strict_syshdr.c,v 1.11 2021/12/22 15:20:08 rillig Exp $ */
|
||||
# 3 "d_c99_bool_strict_syshdr.c"
|
||||
|
||||
/*
|
||||
|
@ -177,3 +177,35 @@ str_equal_good(const char *s1, const char *s2)
|
|||
{
|
||||
return strcmp(s1, s2) == 0;
|
||||
}
|
||||
|
||||
|
||||
int read_char(void);
|
||||
|
||||
void
|
||||
controlling_expression_with_comma_operator(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
while (c = read_char(),
|
||||
# 191 "c_c99_bool_strict_syshdr.c" 3 4
|
||||
((int)((ctype_table + 1)[(
|
||||
# 193 "c_c99_bool_strict_syshdr.c"
|
||||
c
|
||||
# 195 "c_c99_bool_strict_syshdr.c" 3 4
|
||||
)] & 0x0040 /* Space */))
|
||||
# 197 "c_c99_bool_strict_syshdr.c"
|
||||
)
|
||||
/* expect-1: error: controlling expression must be bool, not 'int' [333] */
|
||||
continue;
|
||||
/*
|
||||
* TODO: investigate why lint doesn't accept this call to isspace().
|
||||
* It comes from a system header, therefore type 'int' should be OK.
|
||||
* It is probably because the ',' of the controlling expression
|
||||
* comes from the main source file, and lint assumes that the main
|
||||
* operator of the controlling expression decides its outcome. This
|
||||
* assumption does not hold for the ',' operator since its result
|
||||
* only depends on its right-hand operand.
|
||||
*
|
||||
* Since tree.c 1.395 from 2021-11-16.
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -4,3 +4,4 @@ d_c99_bool_strict_syshdr.c(80): error: operands of 'init' have incompatible type
|
|||
d_c99_bool_strict_syshdr.c(157): error: return value type mismatch (_Bool) and (int) [211]
|
||||
d_c99_bool_strict_syshdr.c(172): error: operand of '!' must be bool, not 'int' [330]
|
||||
d_c99_bool_strict_syshdr.c(172): warning: function 'str_equal_bad' expects to return value [214]
|
||||
c_c99_bool_strict_syshdr.c(197): error: controlling expression must be bool, not 'int' [333]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lex.c,v 1.93 2021/12/22 14:49:11 rillig Exp $ */
|
||||
/* $NetBSD: lex.c,v 1.94 2021/12/22 15:20:08 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID) && !defined(lint)
|
||||
__RCSID("$NetBSD: lex.c,v 1.93 2021/12/22 14:49:11 rillig Exp $");
|
||||
__RCSID("$NetBSD: lex.c,v 1.94 2021/12/22 15:20:08 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
@ -64,9 +64,8 @@ pos_t curr_pos = { "", 1, 0 };
|
|||
*/
|
||||
pos_t csrc_pos = { "", 1, 0 };
|
||||
|
||||
bool in_gcc_attribute; /* Are we parsing a gcc attribute? */
|
||||
|
||||
bool in_system_header = false;
|
||||
bool in_gcc_attribute;
|
||||
bool in_system_header;
|
||||
|
||||
static sbuf_t *allocsb(void);
|
||||
static void freesb(sbuf_t *);
|
||||
|
@ -115,11 +114,8 @@ lex_unknown_character(int c)
|
|||
#define kwdef_gcc_attr(name, token) \
|
||||
kwdef(name, token, 0, 0, 0, 0, 0, 1, 1, 5)
|
||||
|
||||
/*
|
||||
* Keywords.
|
||||
* During initialization they are written to the symbol table.
|
||||
*/
|
||||
static struct kwtab {
|
||||
/* During initialization, these keywords are written to the symbol table. */
|
||||
static struct keyword {
|
||||
const char *kw_name; /* keyword */
|
||||
int kw_token; /* token returned by yylex() */
|
||||
scl_t kw_scl; /* storage class if kw_token T_SCLASS */
|
||||
|
@ -133,7 +129,7 @@ static struct kwtab {
|
|||
bool kw_plain:1; /* 'name' */
|
||||
bool kw_leading:1; /* '__name' */
|
||||
bool kw_both:1; /* '__name__' */
|
||||
} kwtab[] = {
|
||||
} keywords[] = {
|
||||
kwdef_gcc_attr( "alias", T_AT_ALIAS),
|
||||
kwdef_keyword( "_Alignas", T_ALIGNAS),
|
||||
kwdef_keyword( "_Alignof", T_ALIGNOF),
|
||||
|
@ -261,8 +257,7 @@ static struct kwtab {
|
|||
/* Symbol table */
|
||||
static sym_t *symtab[HSHSIZ1];
|
||||
|
||||
/* free list for sbuf structures */
|
||||
static sbuf_t *sbfrlst;
|
||||
static sbuf_t *sbuf_free_list;
|
||||
|
||||
/* type of next expected symbol */
|
||||
symt_t symtyp;
|
||||
|
@ -291,7 +286,7 @@ symtab_remove(sym_t *sym)
|
|||
|
||||
|
||||
static void
|
||||
add_keyword(const struct kwtab *kw, bool leading, bool trailing)
|
||||
add_keyword(const struct keyword *kw, bool leading, bool trailing)
|
||||
{
|
||||
sym_t *sym;
|
||||
char buf[256];
|
||||
|
@ -327,9 +322,9 @@ add_keyword(const struct kwtab *kw, bool leading, bool trailing)
|
|||
void
|
||||
initscan(void)
|
||||
{
|
||||
struct kwtab *kw;
|
||||
struct keyword *kw;
|
||||
|
||||
for (kw = kwtab; kw->kw_name != NULL; kw++) {
|
||||
for (kw = keywords; kw->kw_name != NULL; kw++) {
|
||||
if ((kw->kw_c90 || kw->kw_c99) && tflag)
|
||||
continue;
|
||||
if (kw->kw_c99 && !(Sflag || gflag))
|
||||
|
@ -353,8 +348,8 @@ allocsb(void)
|
|||
{
|
||||
sbuf_t *sb;
|
||||
|
||||
if ((sb = sbfrlst) != NULL) {
|
||||
sbfrlst = sb->sb_next;
|
||||
if ((sb = sbuf_free_list) != NULL) {
|
||||
sbuf_free_list = sb->sb_next;
|
||||
#ifdef BLKDEBUG
|
||||
(void)memset(sb, 0, sizeof(*sb));
|
||||
#else
|
||||
|
@ -375,8 +370,8 @@ freesb(sbuf_t *sb)
|
|||
{
|
||||
|
||||
(void)memset(sb, ZERO, sizeof(*sb));
|
||||
sb->sb_next = sbfrlst;
|
||||
sbfrlst = sb;
|
||||
sb->sb_next = sbuf_free_list;
|
||||
sbuf_free_list = sb;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -421,11 +416,9 @@ hash(const char *s)
|
|||
* If it is a keyword, the token is returned. In some cases it is described
|
||||
* more deeply by data written to yylval.
|
||||
*
|
||||
* If it is a symbol, T_NAME is returned and the pointer to a sbuf struct
|
||||
* is stored in yylval. This struct contains the name of the symbol, its
|
||||
* length and hash value. If there is already a symbol of the same name
|
||||
* and type in the symbol table, the sbuf struct also contains a pointer
|
||||
* to the symbol table entry.
|
||||
* If it is a symbol, T_NAME is returned and the name is stored in yylval.
|
||||
* If there is already a symbol of the same name and type in the symbol
|
||||
* table, yylval.y_name->sb_sym points there.
|
||||
*/
|
||||
extern int
|
||||
lex_name(const char *yytext, size_t yyleng)
|
||||
|
@ -467,7 +460,7 @@ search(sbuf_t *sb)
|
|||
{
|
||||
unsigned int h;
|
||||
sym_t *sym;
|
||||
const struct kwtab *kw;
|
||||
const struct keyword *kw;
|
||||
|
||||
h = hash(sb->sb_name);
|
||||
for (sym = symtab[h]; sym != NULL; sym = sym->s_link) {
|
||||
|
@ -952,7 +945,12 @@ get_escaped_char(int delim)
|
|||
warning(82);
|
||||
v = 0;
|
||||
n = 0;
|
||||
while ((c = inpc()) >= 0 && isxdigit(c)) {
|
||||
/*
|
||||
* TODO: remove the redundant EOF test once the test
|
||||
* controlling_expression_with_comma_operator is
|
||||
* fixed in d_c99_bool_strict_syshdr.c.
|
||||
*/
|
||||
while ((c = inpc()) != EOF && isxdigit(c)) {
|
||||
c = isdigit(c) ?
|
||||
c - '0' : toupper(c) - 'A' + 10;
|
||||
v = (v << 4) + c;
|
||||
|
@ -1018,19 +1016,13 @@ parse_line_directive_flags(const char *p,
|
|||
*is_end = true;
|
||||
if (word_end - word_start == 1 && word_start[0] == '3')
|
||||
*is_system = true;
|
||||
/* Flag '4' would only be interesting if lint handled C++. */
|
||||
/* Flag '4' is only interesting for C++. */
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (*p != '\0') {
|
||||
/* syntax error '%s' */
|
||||
warning(249, "extra character(s) after directive");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for preprocessor directives. Currently implemented are:
|
||||
* # pragma [argument...]
|
||||
* # lineno
|
||||
* # lineno "filename"
|
||||
* # lineno "filename" GCC-flag...
|
||||
|
@ -1059,7 +1051,7 @@ lex_directive(const char *yytext)
|
|||
return;
|
||||
}
|
||||
ln = strtol(--cp, &eptr, 10);
|
||||
if (cp == eptr)
|
||||
if (eptr == cp)
|
||||
goto error;
|
||||
if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0')
|
||||
goto error;
|
||||
|
@ -1148,6 +1140,11 @@ lex_comment(void)
|
|||
eoc = false;
|
||||
|
||||
/* Skip whitespace after the start of the comment */
|
||||
/*
|
||||
* TODO: remove the redundant EOF test once the test
|
||||
* controlling_expression_with_comma_operator is fixed in
|
||||
* d_c99_bool_strict_syshdr.c.
|
||||
*/
|
||||
while ((c = inpc()) != EOF && isspace(c))
|
||||
continue;
|
||||
|
||||
|
@ -1173,13 +1170,13 @@ lex_comment(void)
|
|||
goto skip_rest;
|
||||
|
||||
/* skip whitespace after the keyword */
|
||||
while (c != EOF && isspace(c))
|
||||
while (isspace(c))
|
||||
c = inpc();
|
||||
|
||||
/* read the argument, if the keyword accepts one and there is one */
|
||||
l = 0;
|
||||
if (keywtab[i].arg) {
|
||||
while (c != EOF && isdigit(c) && l < sizeof(arg) - 1) {
|
||||
while (isdigit(c) && l < sizeof(arg) - 1) {
|
||||
arg[l++] = (char)c;
|
||||
c = inpc();
|
||||
}
|
||||
|
@ -1188,7 +1185,7 @@ lex_comment(void)
|
|||
a = l != 0 ? atoi(arg) : -1;
|
||||
|
||||
/* skip whitespace after the argument */
|
||||
while (c != EOF && isspace(c))
|
||||
while (isspace(c))
|
||||
c = inpc();
|
||||
|
||||
if (c != '*' || (c = inpc()) != '/') {
|
||||
|
@ -1237,7 +1234,7 @@ lex_slash_slash_comment(void)
|
|||
|
||||
/*
|
||||
* Clear flags for lint comments LINTED, LONGLONG and CONSTCOND.
|
||||
* clear_warn_flags() is called after function definitions and global and
|
||||
* clear_warn_flags is called after function definitions and global and
|
||||
* local declarations and definitions. It is also called between
|
||||
* the controlling expression and the body of control statements
|
||||
* (if, switch, for, while).
|
||||
|
@ -1253,7 +1250,7 @@ clear_warn_flags(void)
|
|||
|
||||
/*
|
||||
* Strings are stored in a dynamically allocated buffer and passed
|
||||
* in yylval.y_xstrg to the parser. The parser or the routines called
|
||||
* in yylval.y_string to the parser. The parser or the routines called
|
||||
* by the parser are responsible for freeing this buffer.
|
||||
*/
|
||||
int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lint1.h,v 1.132 2021/12/22 14:49:11 rillig Exp $ */
|
||||
/* $NetBSD: lint1.h,v 1.133 2021/12/22 15:20:08 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
|
||||
|
@ -245,7 +245,7 @@ typedef struct sym {
|
|||
pos_t s_set_pos; /* position of first initialization */
|
||||
pos_t s_use_pos; /* position of first use */
|
||||
symt_t s_kind; /* type of symbol */
|
||||
const struct kwtab *s_keyword;
|
||||
const struct keyword *s_keyword;
|
||||
bool s_bitfield:1;
|
||||
bool s_set:1; /* variable set, label defined */
|
||||
bool s_used:1; /* variable/label used */
|
||||
|
|
Loading…
Reference in New Issue