Module Name: src
Committed By: rillig
Date: Sun Mar 3 10:27:18 UTC 2024
Modified Files:
src/tests/usr.bin/xlint/lint1: msg_363.c msg_364.c msg_365.c msg_366.c
msg_367.c msg_374.c msg_377.c
src/usr.bin/xlint/lint1: cksnprintb.c err.c
Log Message:
lint: fix warning about "empty" single-letter snprintb descriptions
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/tests/usr.bin/xlint/lint1/msg_363.c \
src/tests/usr.bin/xlint/lint1/msg_364.c \
src/tests/usr.bin/xlint/lint1/msg_365.c \
src/tests/usr.bin/xlint/lint1/msg_367.c \
src/tests/usr.bin/xlint/lint1/msg_377.c
cvs rdiff -u -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_366.c \
src/tests/usr.bin/xlint/lint1/msg_374.c
cvs rdiff -u -r1.4 -r1.5 src/usr.bin/xlint/lint1/cksnprintb.c
cvs rdiff -u -r1.229 -r1.230 src/usr.bin/xlint/lint1/err.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.1 src/tests/usr.bin/xlint/lint1/msg_363.c:1.2
--- src/tests/usr.bin/xlint/lint1/msg_363.c:1.1 Fri Mar 1 19:39:28 2024
+++ src/tests/usr.bin/xlint/lint1/msg_363.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_363.c,v 1.1 2024/03/01 19:39:28 rillig Exp $ */
+/* $NetBSD: msg_363.c,v 1.2 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_363.c"
// Test for message: non-printing character '%.*s' in description '%.*s' [363]
@@ -33,7 +33,7 @@ old_style_description(unsigned u32)
/* expect+7: warning: bit position '\000' (0) in '\000print' out of range 1..32 [371] */
/* expect+6: warning: old-style format contains '\0' [362] */
/* expect+5: warning: bit position '\n' in '\nable' should be escaped as octal or hex [369] */
- /* expect+4: warning: empty description in '\0' [367] */
+ /* expect+4: warning: redundant '\0' at the end of the format [377] */
snprintb(buf, sizeof(buf),
"\020"
"\001non\000print\nable\0",
Index: src/tests/usr.bin/xlint/lint1/msg_364.c
diff -u src/tests/usr.bin/xlint/lint1/msg_364.c:1.1 src/tests/usr.bin/xlint/lint1/msg_364.c:1.2
--- src/tests/usr.bin/xlint/lint1/msg_364.c:1.1 Fri Mar 1 19:39:28 2024
+++ src/tests/usr.bin/xlint/lint1/msg_364.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_364.c,v 1.1 2024/03/01 19:39:28 rillig Exp $ */
+/* $NetBSD: msg_364.c,v 1.2 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_364.c"
// Test for message: missing bit position after '%.*s' [364]
@@ -26,6 +26,7 @@ example(unsigned u32)
"b",
u32);
+ /* expect+5: warning: empty description in 'b\007' [367] */
/* expect+4: warning: missing '\0' at the end of 'b\007' [366] */
snprintb(buf, sizeof(buf),
"\177\020"
Index: src/tests/usr.bin/xlint/lint1/msg_365.c
diff -u src/tests/usr.bin/xlint/lint1/msg_365.c:1.1 src/tests/usr.bin/xlint/lint1/msg_365.c:1.2
--- src/tests/usr.bin/xlint/lint1/msg_365.c:1.1 Fri Mar 1 19:39:28 2024
+++ src/tests/usr.bin/xlint/lint1/msg_365.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_365.c,v 1.1 2024/03/01 19:39:28 rillig Exp $ */
+/* $NetBSD: msg_365.c,v 1.2 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_365.c"
// Test for message: missing field width after '%.*s' [365]
@@ -25,6 +25,7 @@ example(unsigned u32)
"f\000",
u32);
+ /* expect+5: warning: empty description in 'f\007\010' [367] */
/* expect+4: warning: missing '\0' at the end of 'f\007\010' [366] */
snprintb(buf, sizeof(buf),
"\177\020"
Index: src/tests/usr.bin/xlint/lint1/msg_367.c
diff -u src/tests/usr.bin/xlint/lint1/msg_367.c:1.1 src/tests/usr.bin/xlint/lint1/msg_367.c:1.2
--- src/tests/usr.bin/xlint/lint1/msg_367.c:1.1 Fri Mar 1 19:39:28 2024
+++ src/tests/usr.bin/xlint/lint1/msg_367.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_367.c,v 1.1 2024/03/01 19:39:28 rillig Exp $ */
+/* $NetBSD: msg_367.c,v 1.2 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_367.c"
// Test for message: empty description in '%.*s' [367]
@@ -18,7 +18,46 @@ typedef unsigned long long uint64_t;
int snprintb(char*, size_t, const char*, uint64_t);
void
-example(unsigned u32)
+old_style(unsigned u32)
+{
+ char buf[64];
+
+ /* expect+10: warning: empty description in '\001' [367] */
+ /* expect+9: warning: empty description in '\002' [367] */
+ /* expect+8: warning: empty description in '\003' [367] */
+ /* expect+7: warning: empty description in '\004' [367] */
+ snprintb(buf, sizeof(buf),
+ "\020"
+ "\001"
+ "\002"
+ "\003"
+ "\004",
+ u32);
+
+ /* expect+10: warning: empty description in '\001' [367] */
+ /* expect+9: warning: empty description in '\002' [367] */
+ /* expect+8: warning: empty description in '\003' [367] */
+ /* expect+7: warning: empty description in '\004' [367] */
+ snprintb(buf, sizeof(buf),
+ "\020"
+ "\001" "" ""
+ "\002" "" ""
+ "\003" "" ""
+ "\004" "" "",
+ u32);
+
+ // Single-letter descriptions are not empty.
+ snprintb(buf, sizeof(buf),
+ "\020"
+ "\001a"
+ "\002b"
+ "\003c"
+ "\004d",
+ u32);
+}
+
+void
+new_style(uint64_t u64)
{
char buf[64];
@@ -26,37 +65,55 @@ example(unsigned u32)
snprintb(buf, sizeof(buf),
"\177\020"
"b\000\0",
- u32);
+ u64);
/* expect+4: warning: empty description in 'f\000\010\0' [367] */
snprintb(buf, sizeof(buf),
"\177\020"
"f\000\010\0",
- u32);
+ u64);
// No warning, as 'F' does not take a description.
// If there were a description, it would simply be skipped.
snprintb(buf, sizeof(buf),
"\177\020"
"F\000\010\0",
- u32);
+ u64);
/* expect+4: warning: empty description in '=\000\0' [367] */
snprintb(buf, sizeof(buf),
"\177\020"
"=\000\0",
- u32);
+ u64);
/* expect+4: warning: empty description in ':\000\0' [367] */
snprintb(buf, sizeof(buf),
"\177\020"
":\000\0",
- u32);
+ u64);
/* expect+4: warning: empty description in '*\0' [367] */
snprintb(buf, sizeof(buf),
"\177\020"
"*\0",
- u32);
+ u64);
+ // Single-letter descriptions are not empty.
+ snprintb(buf, sizeof(buf),
+ "\177\020"
+ "b\000b\0"
+ "f\001\001f\0"
+ "F\002\002F\0"
+ "=\000z\0"
+ ":\001o\0"
+ "*d\0",
+ u64 >> 1);
+
+ /* expect+6: warning: empty description in 'b\001""""""\0' [367] */
+ /* expect+5: warning: empty description in 'b\003""""""\0' [367] */
+ snprintb(buf, sizeof(buf),
+ "\177\020"
+ "b\001" "" "" "\0"
+ "b\003" "" "" "\0",
+ u64);
}
Index: src/tests/usr.bin/xlint/lint1/msg_377.c
diff -u src/tests/usr.bin/xlint/lint1/msg_377.c:1.1 src/tests/usr.bin/xlint/lint1/msg_377.c:1.2
--- src/tests/usr.bin/xlint/lint1/msg_377.c:1.1 Sun Mar 3 00:50:41 2024
+++ src/tests/usr.bin/xlint/lint1/msg_377.c Sun Mar 3 10:27:18 2024
@@ -1,12 +1,14 @@
-/* $NetBSD: msg_377.c,v 1.1 2024/03/03 00:50:41 rillig Exp $ */
+/* $NetBSD: msg_377.c,v 1.2 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_377.c"
-// Test for message: redundant '\0' at the end of new-style format [377]
+// Test for message: redundant '\0' at the end of the format [377]
/*
- * Each directive in the new-style format ends with a '\0'. The final '\0'
- * that ends the whole format is provided implicitly by the compiler as part
- * of the string literal.
+ * Each directive in the new-style format ends with a '\0' that needs to be
+ * spelled out.
+ *
+ * In both old-style and new-style formats, the '\0' that ends the whole
+ * format is provided by the compiler as part of the string literal.
*/
/* lint1-extra-flags: -X 351 */
@@ -21,15 +23,18 @@ example(unsigned u32, uint64_t u64)
{
char buf[64];
- /* expect+6: warning: old-style format contains '\0' [362] */
- /* expect+5: warning: empty description in '\0' [367] */
+ /* expect+9: warning: old-style format contains '\0' [362] */
+ /* expect+8: warning: old-style format contains '\0' [362] */
+ /* expect+7: warning: bit position '\000' (0) in '\000out-of-range' out of range 1..32 [371] */
+ /* expect+6: warning: redundant '\0' at the end of the format [377] */
snprintb(buf, sizeof(buf),
"\020"
"\005bit"
+ "\000out-of-range"
"\0",
u32);
- /* expect+5: warning: redundant '\0' at the end of new-style format [377] */
+ /* expect+5: warning: redundant '\0' at the end of the format [377] */
snprintb(buf, sizeof(buf),
"\177\020"
"b\005bit\0"
Index: src/tests/usr.bin/xlint/lint1/msg_366.c
diff -u src/tests/usr.bin/xlint/lint1/msg_366.c:1.2 src/tests/usr.bin/xlint/lint1/msg_366.c:1.3
--- src/tests/usr.bin/xlint/lint1/msg_366.c:1.2 Sun Mar 3 00:50:41 2024
+++ src/tests/usr.bin/xlint/lint1/msg_366.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_366.c,v 1.2 2024/03/03 00:50:41 rillig Exp $ */
+/* $NetBSD: msg_366.c,v 1.3 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_366.c"
// Test for message: missing '\0' at the end of '%.*s' [366]
@@ -24,18 +24,20 @@ example(unsigned u32)
{
char buf[64];
- /* expect+4: warning: redundant '\0' at the end of new-style format [377] */
+ /* expect+4: warning: redundant '\0' at the end of the format [377] */
snprintb(buf, sizeof(buf),
"\177\020"
"\0",
u32);
+ /* expect+5: warning: empty description in 'b\007' [367] */
/* expect+4: warning: missing '\0' at the end of 'b\007' [366] */
snprintb(buf, sizeof(buf),
"\177\020"
"b\007",
u32);
+ /* expect+5: warning: empty description in 'f\007\000' [367] */
/* expect+4: warning: missing '\0' at the end of 'f\007\000' [366] */
snprintb(buf, sizeof(buf),
"\177\020"
Index: src/tests/usr.bin/xlint/lint1/msg_374.c
diff -u src/tests/usr.bin/xlint/lint1/msg_374.c:1.2 src/tests/usr.bin/xlint/lint1/msg_374.c:1.3
--- src/tests/usr.bin/xlint/lint1/msg_374.c:1.2 Sun Mar 3 00:50:41 2024
+++ src/tests/usr.bin/xlint/lint1/msg_374.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: msg_374.c,v 1.2 2024/03/03 00:50:41 rillig Exp $ */
+/* $NetBSD: msg_374.c,v 1.3 2024/03/03 10:27:18 rillig Exp $ */
# 3 "msg_374.c"
// Test for message: unknown directive '%.*s' [374]
@@ -32,7 +32,7 @@ example(uint64_t u64)
"\00012345\0",
u64);
- /* expect+5: warning: redundant '\0' at the end of new-style format [377] */
+ /* expect+5: warning: redundant '\0' at the end of the format [377] */
snprintb(buf, sizeof(buf),
"\177\020"
"b\00012345\0"
Index: src/usr.bin/xlint/lint1/cksnprintb.c
diff -u src/usr.bin/xlint/lint1/cksnprintb.c:1.4 src/usr.bin/xlint/lint1/cksnprintb.c:1.5
--- src/usr.bin/xlint/lint1/cksnprintb.c:1.4 Sun Mar 3 00:50:41 2024
+++ src/usr.bin/xlint/lint1/cksnprintb.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: cksnprintb.c,v 1.4 2024/03/03 00:50:41 rillig Exp $ */
+/* $NetBSD: cksnprintb.c,v 1.5 2024/03/03 10:27:18 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.4 2024/03/03 00:50:41 rillig Exp $");
+__RCSID("$NetBSD: cksnprintb.c,v 1.5 2024/03/03 10:27:18 rillig Exp $");
#endif
#include <stdbool.h>
@@ -180,6 +180,40 @@ check_reachable(checker *ck, uint64_t di
}
}
+static void
+parse_description(const checker *ck, quoted_iterator *it,
+ bool *seen_null, bool *descr_empty)
+{
+ bool new_style = ck->new_style;
+
+ quoted_iterator first = *it;
+ (void)quoted_next(ck->fmt, &first);
+ size_t descr_start = first.start, descr_end = descr_start;
+
+ for (quoted_iterator peek = *it; quoted_next(ck->fmt, &peek);) {
+ if (new_style && peek.value == 0) {
+ *seen_null = true;
+ *it = peek;
+ break;
+ }
+ if (!new_style && peek.value == 0)
+ /* old-style format contains '\0' */
+ warning(362);
+ if (!new_style && peek.value <= 32)
+ break;
+ *it = peek;
+ descr_end = peek.i;
+ if (peek.escaped && !isprint((unsigned char)peek.value)) {
+ /* non-printing character '%.*s' in description ... */
+ warning(363,
+ len(*it), start(*it, ck->fmt),
+ (int)(descr_end - descr_start),
+ ck->fmt->data + descr_start);
+ }
+ }
+ *descr_empty = descr_start == descr_end;
+}
+
static bool
check_directive(const buffer *fmt, quoted_iterator *it, bool new_style,
checker *ck)
@@ -218,16 +252,11 @@ check_directive(const buffer *fmt, quote
quoted_iterator cmp = *it;
bool has_default = new_style && dir.value == '*';
- if (has_default && !quoted_next(fmt, it)) {
- /* missing '\0' at the end of '%.*s' */
- warning(366, range(dir, *it), start(dir, fmt));
- return false;
- }
- if (new_style && dir.value == '\0') {
+ if (dir.value == '\0') {
quoted_iterator end = *it;
if (!quoted_next(fmt, &end)) {
- /* redundant '\0' at the end of new-style format */
+ /* redundant '\0' at the end of the format */
warning(377);
return false;
}
@@ -239,44 +268,9 @@ check_directive(const buffer *fmt, quote
return false;
}
- if (!quoted_next(fmt, it)) {
- if (new_style && dir.value != '*')
- /* missing '\0' at the end of '%.*s' */
- warning(366, range(dir, *it), start(dir, fmt));
- else
- /* empty description in '%.*s' */
- warning(367, range(dir, *it), start(dir, fmt));
- return false;
- }
- quoted_iterator descr = *it;
-
- quoted_iterator prev = *it;
- for (;;) {
- if (new_style && it->value == 0)
- break;
- if (!new_style && it->value == 0)
- /* old-style format contains '\0' */
- warning(362);
- if (!new_style && it->value <= 32) {
- *it = prev;
- break;
- }
- if (it->escaped && !isprint((unsigned char)it->value)) {
- /* non-printing character '%.*s' in description ... */
- warning(363,
- len(*it), start(*it, fmt),
- range(descr, *it), start(descr, fmt));
- }
- prev = *it;
- if (!quoted_next(fmt, it)) {
- if (new_style) {
- /* missing '\0' at the end of '%.*s' */
- warning(366, range(dir, prev),
- start(dir, fmt));
- }
- break;
- }
- }
+ bool needs_descr = !(new_style && dir.value == 'F');
+ bool seen_null = false, descr_empty = false;
+ parse_description(ck, it, &seen_null, &descr_empty);
if (has_bit)
check_hex_escape(fmt, bit);
@@ -311,8 +305,8 @@ check_directive(const buffer *fmt, quote
warning(373, val(bit) + val(width),
range(dir, *it), start(dir, fmt));
}
- if (has_cmp && ck->field_width < 64
- && cmp.value & ~(uint64_t)0 << ck->field_width) {
+ if (has_cmp && ck->field_width > 0 && ck->field_width < 64
+ && cmp.value & ~value_bits((unsigned)ck->field_width)) {
/* comparison value '%.*s' (%ju) exceeds maximum field ... */
warning(375, len(cmp), start(cmp, fmt), val(cmp),
(uintmax_t)value_bits((unsigned)ck->field_width));
@@ -325,10 +319,14 @@ check_directive(const buffer *fmt, quote
uint64_t w = has_width ? width.value : 1;
check_reachable(ck, bit.value, w, dir.start, it->i);
}
- if (descr.i == prev.i && dir.value != 'F') {
+ if (needs_descr && descr_empty) {
/* empty description in '%.*s' */
warning(367, range(dir, *it), start(dir, fmt));
}
+ if (new_style && !seen_null) {
+ /* missing '\0' at the end of '%.*s' */
+ warning(366, range(dir, *it), start(dir, fmt));
+ }
if (has_width)
ck->field_width = width.value;
Index: src/usr.bin/xlint/lint1/err.c
diff -u src/usr.bin/xlint/lint1/err.c:1.229 src/usr.bin/xlint/lint1/err.c:1.230
--- src/usr.bin/xlint/lint1/err.c:1.229 Sun Mar 3 00:50:41 2024
+++ src/usr.bin/xlint/lint1/err.c Sun Mar 3 10:27:18 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: err.c,v 1.229 2024/03/03 00:50:41 rillig Exp $ */
+/* $NetBSD: err.c,v 1.230 2024/03/03 10:27:18 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: err.c,v 1.229 2024/03/03 00:50:41 rillig Exp $");
+__RCSID("$NetBSD: err.c,v 1.230 2024/03/03 10:27:18 rillig Exp $");
#endif
#include <limits.h>
@@ -432,7 +432,7 @@ static const char *const msgs[] = {
"unknown directive '%.*s'", // 374
"comparison value '%.*s' (%ju) exceeds maximum field value %ju", // 375
"'%.*s' overlaps earlier '%.*s' on bit %u", // 376
- "redundant '\\0' at the end of new-style format", // 377
+ "redundant '\\0' at the end of the format", // 377
"directive '%.*s' is unreachable by input value", // 378
};