Module Name:    src
Committed By:   rillig
Date:           Wed Dec 22 15:20:08 UTC 2021

Modified Files:
        src/tests/usr.bin/xlint/lint1: d_c99_bool_strict_syshdr.c
            d_c99_bool_strict_syshdr.exp
        src/usr.bin/xlint/lint1: lex.c lint1.h

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c
cvs rdiff -u -r1.12 -r1.13 \
    src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
cvs rdiff -u -r1.93 -r1.94 src/usr.bin/xlint/lint1/lex.c
cvs rdiff -u -r1.132 -r1.133 src/usr.bin/xlint/lint1/lint1.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.10 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.11
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c:1.10	Tue Dec 21 16:25:14 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.c	Wed Dec 22 15:20:08 2021
@@ -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 cha
 {
 	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.
+	 */
+}

Index: src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp
diff -u src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.12 src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.13
--- src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp:1.12	Tue Dec 21 16:25:14 2021
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool_strict_syshdr.exp	Wed Dec 22 15:20:08 2021
@@ -4,3 +4,4 @@ d_c99_bool_strict_syshdr.c(80): error: o
 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]

Index: src/usr.bin/xlint/lint1/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.93 src/usr.bin/xlint/lint1/lex.c:1.94
--- src/usr.bin/xlint/lint1/lex.c:1.93	Wed Dec 22 14:49:11 2021
+++ src/usr.bin/xlint/lint1/lex.c	Wed Dec 22 15:20:08 2021
@@ -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
 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

Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.132 src/usr.bin/xlint/lint1/lint1.h:1.133
--- src/usr.bin/xlint/lint1/lint1.h:1.132	Wed Dec 22 14:49:11 2021
+++ src/usr.bin/xlint/lint1/lint1.h	Wed Dec 22 15:20:08 2021
@@ -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 */

Reply via email to