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; }