Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: fix crash from ckgetopt.c 1.2 and ...
details: https://anonhg.NetBSD.org/src/rev/3ae81cabeee8
branches: trunk
changeset: 952872:3ae81cabeee8
user: rillig <rillig%NetBSD.org@localhost>
date: Sat Feb 20 09:57:02 2021 +0000
description:
lint: fix crash from ckgetopt.c 1.2 and document the data structures
diffstat:
usr.bin/xlint/lint1/ckgetopt.c | 35 ++++++++++++++++++++++++++++-------
1 files changed, 28 insertions(+), 7 deletions(-)
diffs (80 lines):
diff -r 98dbfd45affb -r 3ae81cabeee8 usr.bin/xlint/lint1/ckgetopt.c
--- a/usr.bin/xlint/lint1/ckgetopt.c Sat Feb 20 09:51:20 2021 +0000
+++ b/usr.bin/xlint/lint1/ckgetopt.c Sat Feb 20 09:57:02 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ckgetopt.c,v 1.3 2021/02/20 01:18:02 christos Exp $ */
+/* $NetBSD: ckgetopt.c,v 1.4 2021/02/20 09:57:02 rillig Exp $ */
/*-
* Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: ckgetopt.c,v 1.3 2021/02/20 01:18:02 christos Exp $");
+__RCSID("$NetBSD: ckgetopt.c,v 1.4 2021/02/20 09:57:02 rillig Exp $");
#endif
#include <stdbool.h>
@@ -51,10 +51,28 @@
*/
struct {
+ /*
+ * 0 means outside a while loop with a getopt call.
+ * 1 means directly inside a while loop with a getopt call.
+ * > 1 means in a nested while loop; this is used for finishing the
+ * check at the correct point.
+ */
+ int while_level;
+
+ /*
+ * The options string from the getopt call. Whenever an option is
+ * handled by a case label, it is set to ' ' in unhandled_options.
+ * In the end, only ' ' and ':' should remain in unhandled_options.
+ */
pos_t options_pos;
char *options;
char *unhandled_options;
- int while_level;
+
+ /*
+ * The nesting level of switch statements, is only modified if
+ * while_level > 0. Only the case labels at switch_level == 1 are
+ * relevant, all nested case labels are ignored.
+ */
int switch_level;
} ck;
@@ -100,7 +118,9 @@
static void
check_unlisted_option(char opt)
{
- if (opt == '?' || ck.options == NULL)
+ lint_assert(ck.options != NULL);
+
+ if (opt == '?')
return;
const char *optptr = strchr(ck.options, opt);
@@ -116,8 +136,7 @@
static void
check_unhandled_option(void)
{
- if (ck.unhandled_options == NULL)
- return;
+ lint_assert(ck.unhandled_options != NULL);
for (const char *opt = ck.unhandled_options; *opt != '\0'; opt++) {
if (*opt == ' ' || *opt == ':')
@@ -135,7 +154,9 @@
void
check_getopt_begin_while(const tnode_t *tn)
{
- if (ck.while_level == 0 && is_getopt_call(tn, &ck.options)) {
+ if (ck.while_level == 0) {
+ if (!is_getopt_call(tn, &ck.options))
+ return;
ck.unhandled_options = xstrdup(ck.options);
ck.options_pos = curr_pos;
}
Home |
Main Index |
Thread Index |
Old Index