Module Name: src
Committed By: rillig
Date: Sun Mar 3 16:09:01 UTC 2024
Modified Files:
src/tests/usr.bin/xlint/lint1: msg_363.c
src/usr.bin/xlint/lint1: ckgetopt.c cksnprintb.c emit1.c init.c lex.c
lint1.h tree.c
Log Message:
lint: clean up string parsing and snprintb check
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/tests/usr.bin/xlint/lint1/msg_363.c
cvs rdiff -u -r1.24 -r1.25 src/usr.bin/xlint/lint1/ckgetopt.c
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/xlint/lint1/cksnprintb.c
cvs rdiff -u -r1.89 -r1.90 src/usr.bin/xlint/lint1/emit1.c
cvs rdiff -u -r1.260 -r1.261 src/usr.bin/xlint/lint1/init.c
cvs rdiff -u -r1.221 -r1.222 src/usr.bin/xlint/lint1/lex.c
cvs rdiff -u -r1.214 -r1.215 src/usr.bin/xlint/lint1/lint1.h
cvs rdiff -u -r1.608 -r1.609 src/usr.bin/xlint/lint1/tree.c
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/msg_363.c
diff -u src/tests/usr.bin/xlint/lint1/msg_363.c:1.3 src/tests/usr.bin/xlint/lint1/msg_363.c:1.4
--- src/tests/usr.bin/xlint/lint1/msg_363.c:1.3 Sun Mar 3 13:09:23 2024
+++ src/tests/usr.bin/xlint/lint1/msg_363.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_363.c,v 1.3 2024/03/03 13:09:23 rillig Exp $ */
+/* $NetBSD: msg_363.c,v 1.4 2024/03/03 16:09:01 rillig Exp $ */
# 3 "msg_363.c"
// Test for message: non-printing character '%.*s' in description '%.*s' [363]
@@ -29,6 +29,18 @@ old_style_description(unsigned u32)
"\001non\tprint\nable\377",
u32);
+ /* expect+10: warning: non-printing character '\177' in description '\177' [363] */
+ /* expect+9: warning: non-printing character '\177' in description 'aa""""\177' [363] */
+ /* expect+8: warning: non-printing character '\177' in description 'bb""\177' [363] */
+ /* expect+7: warning: non-printing character '\177' in description 'cc\177' [363] */
+ snprintb(buf, sizeof(buf),
+ "\020"
+ "\002""\177"
+ "\003aa""""\177"
+ "\004""bb""\177"
+ "\005""""cc\177",
+ u32);
+
/* expect+6: warning: bit position '\000' (0) in '\000print' out of range 1..32 [371] */
/* expect+5: warning: bit position '\n' in '\nable' should be escaped as octal or hex [369] */
/* expect+4: warning: redundant '\0' at the end of the format [377] */
Index: src/usr.bin/xlint/lint1/ckgetopt.c
diff -u src/usr.bin/xlint/lint1/ckgetopt.c:1.24 src/usr.bin/xlint/lint1/ckgetopt.c:1.25
--- src/usr.bin/xlint/lint1/ckgetopt.c:1.24 Fri Mar 1 21:52:48 2024
+++ src/usr.bin/xlint/lint1/ckgetopt.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: ckgetopt.c,v 1.24 2024/03/01 21:52:48 rillig Exp $ */
+/* $NetBSD: ckgetopt.c,v 1.25 2024/03/03 16:09:01 rillig Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: ckgetopt.c,v 1.24 2024/03/01 21:52:48 rillig Exp $");
+__RCSID("$NetBSD: ckgetopt.c,v 1.25 2024/03/03 16:09:01 rillig Exp $");
#endif
#include <stdbool.h>
@@ -105,7 +105,7 @@ is_getopt_condition(const tnode_t *tn, c
&& (str = last_arg->tn_left->tn_left->tn_string)->data != NULL) {
buffer buf;
buf_init(&buf);
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
while (quoted_next(str, &it))
buf_add_char(&buf, (char)it.value);
*out_options = buf.data;
Index: src/usr.bin/xlint/lint1/cksnprintb.c
diff -u src/usr.bin/xlint/lint1/cksnprintb.c:1.6 src/usr.bin/xlint/lint1/cksnprintb.c:1.7
--- src/usr.bin/xlint/lint1/cksnprintb.c:1.6 Sun Mar 3 13:09:22 2024
+++ src/usr.bin/xlint/lint1/cksnprintb.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: cksnprintb.c,v 1.6 2024/03/03 13:09:22 rillig Exp $ */
+/* $NetBSD: cksnprintb.c,v 1.7 2024/03/03 16:09:01 rillig Exp $ */
/*-
* Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: cksnprintb.c,v 1.6 2024/03/03 13:09:22 rillig Exp $");
+__RCSID("$NetBSD: cksnprintb.c,v 1.7 2024/03/03 16:09:01 rillig Exp $");
#endif
#include <stdbool.h>
@@ -90,13 +90,13 @@ match_snprintb_call(const function_call
static int
len(quoted_iterator it)
{
- return (int)(it.i - it.start);
+ return (int)(it.end - it.start);
}
static int
range(quoted_iterator start, quoted_iterator end)
{
- return (int)(end.i - start.start);
+ return (int)(end.end - start.start);
}
static const char *
@@ -117,7 +117,7 @@ check_hex_escape(const buffer *buf, quot
if (it.hex_digits > 1) {
bool upper = false;
bool lower = false;
- for (size_t i = it.start + 2; i < it.i; i++) {
+ for (size_t i = it.start + 2; i < it.end; i++) {
if (isupper((unsigned char)buf->data[i]))
upper = true;
if (islower((unsigned char)buf->data[i]))
@@ -181,31 +181,28 @@ check_reachable(checker *ck, uint64_t di
warning(378, (int)(end - start), ck->fmt->data + start);
}
-static void
-parse_description(checker *ck, bool *seen_null, bool *descr_empty)
+static bool
+parse_description(checker *ck)
{
- quoted_iterator first = ck->it;
- (void)quoted_next(ck->fmt, &first);
- size_t descr_start = first.start, descr_end = descr_start;
-
- for (quoted_iterator peek = ck->it; quoted_next(ck->fmt, &peek);) {
- if (!ck->new_style && peek.value <= 32)
- break;
- ck->it = peek;
- if (ck->new_style && peek.value == 0) {
- *seen_null = true;
- break;
- }
- descr_end = peek.i;
- if (peek.escaped && !isprint((unsigned char)peek.value)) {
+ size_t descr_start = 0 /* dummy */;
+ bool seen_descr = false;
+ quoted_iterator it = ck->it;
+ uint64_t end_marker = ck->new_style ? 0 : 32;
+
+ while (quoted_next(ck->fmt, &it) && it.value > end_marker) {
+ ck->it = it;
+ if (!seen_descr)
+ descr_start = it.start;
+ seen_descr = true;
+ if (it.escaped && !isprint((unsigned char)it.value)) {
/* non-printing character '%.*s' in description ... */
warning(363,
- len(ck->it), start(ck->it, ck->fmt),
- (int)(descr_end - descr_start),
+ len(it), start(it, ck->fmt),
+ (int)(it.end - descr_start),
ck->fmt->data + descr_start);
}
}
- *descr_empty = descr_start == descr_end;
+ return seen_descr;
}
static bool
@@ -268,8 +265,9 @@ check_directive(checker *ck)
warning(362, len(dir), start(dir, fmt));
bool needs_descr = !(new_style && dir.value == 'F');
- bool seen_null = false, descr_empty = false;
- parse_description(ck, &seen_null, &descr_empty);
+ bool seen_descr = parse_description(ck);
+ bool seen_null = new_style
+ && quoted_next(ck->fmt, &ck->it) && ck->it.value == 0;
if (has_bit)
check_hex_escape(fmt, bit);
@@ -311,10 +309,10 @@ check_directive(checker *ck)
}
if (has_bit) {
uint64_t w = has_width ? width.value : 1;
- check_overlap(ck, bit.value, w, dir.start, it->i);
- check_reachable(ck, bit.value, w, dir.start, it->i);
+ check_overlap(ck, bit.value, w, dir.start, it->end);
+ check_reachable(ck, bit.value, w, dir.start, it->end);
}
- if (needs_descr && descr_empty)
+ if (needs_descr && !seen_descr)
/* empty description in '%.*s' */
warning(367, range(dir, *it), start(dir, fmt));
if (new_style && !seen_null)
Index: src/usr.bin/xlint/lint1/emit1.c
diff -u src/usr.bin/xlint/lint1/emit1.c:1.89 src/usr.bin/xlint/lint1/emit1.c:1.90
--- src/usr.bin/xlint/lint1/emit1.c:1.89 Sat Mar 2 09:32:18 2024
+++ src/usr.bin/xlint/lint1/emit1.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: emit1.c,v 1.89 2024/03/02 09:32:18 rillig Exp $ */
+/* $NetBSD: emit1.c,v 1.90 2024/03/03 16:09:01 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: emit1.c,v 1.89 2024/03/02 09:32:18 rillig Exp $");
+__RCSID("$NetBSD: emit1.c,v 1.90 2024/03/03 16:09:01 rillig Exp $");
#endif
#include <stdlib.h>
@@ -362,7 +362,7 @@ outcall(const tnode_t *tn, bool retval_u
arg->tn_left->tn_string->data != NULL) {
buffer buf;
buf_init(&buf);
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
while (quoted_next(arg->tn_left->tn_string, &it))
buf_add_char(&buf, (char)it.value);
Index: src/usr.bin/xlint/lint1/init.c
diff -u src/usr.bin/xlint/lint1/init.c:1.260 src/usr.bin/xlint/lint1/init.c:1.261
--- src/usr.bin/xlint/lint1/init.c:1.260 Fri Mar 1 21:52:48 2024
+++ src/usr.bin/xlint/lint1/init.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: init.c,v 1.260 2024/03/01 21:52:48 rillig Exp $ */
+/* $NetBSD: init.c,v 1.261 2024/03/03 16:09:01 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: init.c,v 1.260 2024/03/01 21:52:48 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.261 2024/03/03 16:09:01 rillig Exp $");
#endif
#include <stdlib.h>
@@ -886,7 +886,7 @@ initialization_init_array_from_string(in
size_t len = tn->tn_string->len;
if (tn->tn_string->data != NULL) {
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
for (len = 0; quoted_next(tn->tn_string, &it); len++)
continue;
}
Index: src/usr.bin/xlint/lint1/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.221 src/usr.bin/xlint/lint1/lex.c:1.222
--- src/usr.bin/xlint/lint1/lex.c:1.221 Sat Mar 2 09:32:18 2024
+++ src/usr.bin/xlint/lint1/lex.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.221 2024/03/02 09:32:18 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.222 2024/03/03 16:09:01 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: lex.c,v 1.221 2024/03/02 09:32:18 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.222 2024/03/03 16:09:01 rillig Exp $");
#endif
#include <ctype.h>
@@ -726,50 +726,53 @@ read_quoted(bool *complete, char delim,
return buf;
}
+/*
+ * Analyze the lexical representation of the next character in the string
+ * literal list. At the end, only update the position information.
+ */
bool
quoted_next(const buffer *lit, quoted_iterator *it)
{
const char *s = lit->data;
- size_t len = lit->len;
- *it = (quoted_iterator){ .i = it->i, .start = it->i };
+ *it = (quoted_iterator){ .start = it->end };
char delim = s[s[0] == 'L' ? 1 : 0];
- bool in_the_middle = it->i > 0;
- if (it->i == 0) {
+ bool in_the_middle = it->start > 0;
+ if (!in_the_middle) {
it->start = s[0] == 'L' ? 2 : 1;
- it->i = it->start;
+ it->end = it->start;
}
- for (;;) {
- if (s[it->i] != delim)
- break;
- if (it->i + 1 == len)
+ while (s[it->start] == delim) {
+ if (it->start + 1 == lit->len) {
+ it->end = it->start;
return false;
+ }
it->next_literal = in_the_middle;
it->start += 2;
- it->i += 2;
}
+ it->end = it->start;
again:
- switch (s[it->i]) {
+ switch (s[it->end]) {
case '\\':
- it->i++;
+ it->end++;
goto backslash;
case '\n':
it->unescaped_newline = true;
return false;
default:
- it->value = (unsigned char)s[it->i++];
+ it->value = (unsigned char)s[it->end++];
return true;
}
backslash:
it->escaped = true;
- if ('0' <= s[it->i] && s[it->i] <= '7')
+ if ('0' <= s[it->end] && s[it->end] <= '7')
goto octal_escape;
- switch (s[it->i++]) {
+ switch (s[it->end++]) {
case '\n':
goto again;
case 'a':
@@ -825,19 +828,19 @@ backslash:
case '\'':
case '\\':
it->literal_escape = true;
- it->value = (unsigned char)s[it->i - 1];
+ it->value = (unsigned char)s[it->end - 1];
return true;
}
octal_escape:
it->octal_digits++;
- it->value = s[it->i++] - '0';
- if ('0' <= s[it->i] && s[it->i] <= '7') {
+ it->value = s[it->end++] - '0';
+ if ('0' <= s[it->end] && s[it->end] <= '7') {
it->octal_digits++;
- it->value = 8 * it->value + (s[it->i++] - '0');
- if ('0' <= s[it->i] && s[it->i] <= '7') {
+ it->value = 8 * it->value + (s[it->end++] - '0');
+ if ('0' <= s[it->end] && s[it->end] <= '7') {
it->octal_digits++;
- it->value = 8 * it->value + (s[it->i++] - '0');
+ it->value = 8 * it->value + (s[it->end++] - '0');
it->overflow = it->value > TARG_UCHAR_MAX
&& s[0] != 'L';
}
@@ -846,7 +849,7 @@ octal_escape:
hex_escape:
for (;;) {
- char ch = s[it->i];
+ char ch = s[it->end];
unsigned digit_value;
if ('0' <= ch && ch <= '9')
digit_value = ch - '0';
@@ -857,7 +860,7 @@ hex_escape:
else
break;
- it->i++;
+ it->end++;
it->value = 16 * it->value + digit_value;
uint64_t limit = s[0] == 'L' ? TARG_UINT_MAX : TARG_UCHAR_MAX;
if (it->value > limit)
@@ -872,7 +875,7 @@ hex_escape:
static void
check_quoted(const buffer *buf, bool complete, char delim)
{
- quoted_iterator it = { .i = 0 }, prev = it;
+ quoted_iterator it = { .end = 0 }, prev = it;
for (; quoted_next(buf, &it); prev = it) {
if (it.missing_hex_digits)
/* no hex digits follow \x */
@@ -898,7 +901,7 @@ check_quoted(const buffer *buf, bool com
/* \v undefined in traditional C */
warning(264);
else {
- unsigned char ch = buf->data[it.i - 1];
+ unsigned char ch = buf->data[it.end - 1];
if (isprint(ch))
/* dubious escape \%c */
warning(79, ch);
@@ -919,7 +922,7 @@ check_quoted(const buffer *buf, bool com
if (prev.octal_digits > 0 && prev.octal_digits < 3
&& !it.escaped && it.value >= '8' && it.value <= '9')
/* short octal escape '%.*s' followed by digit '%c' */
- warning(356, (int)(prev.i - prev.start),
+ warning(356, (int)(prev.end - prev.start),
buf->data + prev.start, buf->data[it.start]);
}
if (it.unescaped_newline)
@@ -950,7 +953,7 @@ lex_character_constant(void)
size_t n = 0;
uint64_t val = 0;
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
while (quoted_next(buf, &it)) {
val = (val << CHAR_SIZE) + it.value;
n++;
@@ -992,7 +995,7 @@ lex_wide_character_constant(void)
static char wbuf[MB_LEN_MAX + 1];
size_t n = 0, nmax = MB_CUR_MAX;
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
while (quoted_next(buf, &it)) {
if (n < nmax)
wbuf[n] = (char)it.value;
@@ -1294,7 +1297,7 @@ lex_wide_string(void)
buffer str;
buf_init(&str);
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
while (quoted_next(buf, &it))
buf_add_char(&str, (char)it.value);
Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.214 src/usr.bin/xlint/lint1/lint1.h:1.215
--- src/usr.bin/xlint/lint1/lint1.h:1.214 Mon Feb 5 23:11:22 2024
+++ src/usr.bin/xlint/lint1/lint1.h Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.214 2024/02/05 23:11:22 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.215 2024/03/03 16:09:01 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -532,7 +532,7 @@ typedef enum {
typedef struct {
size_t start;
- size_t i;
+ size_t end;
uint64_t value;
bool escaped; /* \n, \003, \x24 */
bool named_escape; /* \a, \n, etc. */
Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.608 src/usr.bin/xlint/lint1/tree.c:1.609
--- src/usr.bin/xlint/lint1/tree.c:1.608 Sun Mar 3 00:50:41 2024
+++ src/usr.bin/xlint/lint1/tree.c Sun Mar 3 16:09:01 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.608 2024/03/03 00:50:41 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.609 2024/03/03 16:09:01 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.608 2024/03/03 00:50:41 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.609 2024/03/03 16:09:01 rillig Exp $");
#endif
#include <float.h>
@@ -529,7 +529,7 @@ build_string(buffer *lit)
{
size_t value_len = lit->len;
if (lit->data != NULL) {
- quoted_iterator it = { .i = 0 };
+ quoted_iterator it = { .end = 0 };
for (value_len = 0; quoted_next(lit, &it); value_len++)
continue;
}