Module Name:    src
Committed By:   rillig
Date:           Thu Feb  1 21:19:13 UTC 2024

Modified Files:
        src/usr.bin/xlint/common: externs.h tyname.c
        src/usr.bin/xlint/lint1: lex.c tree.c

Log Message:
lint: reuse buffer editing code across lint1

Fix cat_strings to update the capacity of the buffer, to prevent
quadratic runtime when concatenating string literals.


To generate a diff of this commit:
cvs rdiff -u -r1.34 -r1.35 src/usr.bin/xlint/common/externs.h
cvs rdiff -u -r1.59 -r1.60 src/usr.bin/xlint/common/tyname.c
cvs rdiff -u -r1.205 -r1.206 src/usr.bin/xlint/lint1/lex.c
cvs rdiff -u -r1.600 -r1.601 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/usr.bin/xlint/common/externs.h
diff -u src/usr.bin/xlint/common/externs.h:1.34 src/usr.bin/xlint/common/externs.h:1.35
--- src/usr.bin/xlint/common/externs.h:1.34	Sat Jan 20 12:02:09 2024
+++ src/usr.bin/xlint/common/externs.h	Thu Feb  1 21:19:13 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: externs.h,v 1.34 2024/01/20 12:02:09 rillig Exp $	*/
+/*	$NetBSD: externs.h,v 1.35 2024/02/01 21:19:13 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,6 +37,8 @@
 #if IS_LINT1 || IS_LINT2
 const char *type_name(const type_t *);
 const char *tspec_name(tspec_t);
+void buf_init(buffer *);
+void buf_add_char(buffer *, char);
 #endif
 
 /*

Index: src/usr.bin/xlint/common/tyname.c
diff -u src/usr.bin/xlint/common/tyname.c:1.59 src/usr.bin/xlint/common/tyname.c:1.60
--- src/usr.bin/xlint/common/tyname.c:1.59	Thu Feb  1 18:37:06 2024
+++ src/usr.bin/xlint/common/tyname.c	Thu Feb  1 21:19:13 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tyname.c,v 1.59 2024/02/01 18:37:06 rillig Exp $	*/
+/*	$NetBSD: tyname.c,v 1.60 2024/02/01 21:19:13 rillig Exp $	*/
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: tyname.c,v 1.59 2024/02/01 18:37:06 rillig Exp $");
+__RCSID("$NetBSD: tyname.c,v 1.60 2024/02/01 21:19:13 rillig Exp $");
 #endif
 
 #include <assert.h>
@@ -94,7 +94,7 @@ intern(const char *name)
 	return n->ntn_name;
 }
 
-static void
+void
 buf_init(buffer *buf)
 {
 	buf->len = 0;
@@ -110,17 +110,28 @@ buf_done(buffer *buf)
 }
 
 static void
-buf_add(buffer *buf, const char *s)
+buf_add_mem(buffer *buf, const char *s, size_t n)
 {
-	size_t len = strlen(s);
-
-	while (buf->len + len + 1 >= buf->cap) {
-		buf->data = xrealloc(buf->data, 2 * buf->cap);
-		buf->cap = 2 * buf->cap;
+	while (buf->len + n + 1 >= buf->cap) {
+		buf->cap *= 2;
+		buf->data = xrealloc(buf->data, buf->cap);
 	}
 
-	memcpy(buf->data + buf->len, s, len + 1);
-	buf->len += len;
+	memcpy(buf->data + buf->len, s, n);
+	buf->len += n;
+	buf->data[buf->len] = '\0';
+}
+
+void
+buf_add_char(buffer *buf, char c)
+{
+	buf_add_mem(buf, &c, 1);
+}
+
+static void
+buf_add(buffer *buf, const char *s)
+{
+	buf_add_mem(buf, s, strlen(s));
 }
 
 static void

Index: src/usr.bin/xlint/lint1/lex.c
diff -u src/usr.bin/xlint/lint1/lex.c:1.205 src/usr.bin/xlint/lint1/lex.c:1.206
--- src/usr.bin/xlint/lint1/lex.c:1.205	Thu Feb  1 18:37:06 2024
+++ src/usr.bin/xlint/lint1/lex.c	Thu Feb  1 21:19:13 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lex.c,v 1.205 2024/02/01 18:37:06 rillig Exp $ */
+/* $NetBSD: lex.c,v 1.206 2024/02/01 21:19:13 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.205 2024/02/01 18:37:06 rillig Exp $");
+__RCSID("$NetBSD: lex.c,v 1.206 2024/02/01 21:19:13 rillig Exp $");
 #endif
 
 #include <ctype.h>
@@ -1259,27 +1259,18 @@ clear_warn_flags(void)
 int
 lex_string(void)
 {
-	size_t s_len = 0;
-	size_t s_cap = 64;
-	char *s = xmalloc(s_cap);
+	buffer *buf = xcalloc(1, sizeof(*buf));
+	buf_init(buf);
 
 	int c;
-	while ((c = get_escaped_char('"')) >= 0) {
-		/* +1 to reserve space for a trailing NUL character */
-		if (s_len + 1 == s_cap)
-			s = xrealloc(s, s_cap *= 2);
-		s[s_len++] = (char)c;
-	}
-	s[s_len] = '\0';
+	while ((c = get_escaped_char('"')) >= 0)
+		buf_add_char(buf, (char)c);
 	if (c == -2)
 		/* unterminated string constant */
 		error(258);
 
-	buffer *str = xcalloc(1, sizeof(*str));
-	str->len = s_len;
-	str->data = s;
 
-	yylval.y_string = str;
+	yylval.y_string = buf;
 	return T_STRING;
 }
 
@@ -1288,15 +1279,10 @@ lex_wide_string(void)
 {
 	int c, n;
 
-	size_t len = 0, max = 64;
-	char *s = xmalloc(max);
-	while ((c = get_escaped_char('"')) >= 0) {
-		/* +1 to save space for a trailing NUL character */
-		if (len + 1 >= max)
-			s = xrealloc(s, max *= 2);
-		s[len++] = (char)c;
-	}
-	s[len] = '\0';
+	buffer buf;
+	buf_init(&buf);
+	while ((c = get_escaped_char('"')) >= 0)
+		buf_add_char(&buf, (char)c);
 	if (c == -2)
 		/* unterminated string constant */
 		error(258);
@@ -1304,8 +1290,8 @@ lex_wide_string(void)
 	/* get length of wide-character string */
 	(void)mblen(NULL, 0);
 	size_t wlen = 0;
-	for (size_t i = 0; i < len; i += n, wlen++) {
-		if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) {
+	for (size_t i = 0; i < buf.len; i += n, wlen++) {
+		if ((n = mblen(buf.data + i, MB_CUR_MAX)) == -1) {
 			/* invalid multibyte character */
 			error(291);
 			break;
@@ -1318,13 +1304,13 @@ lex_wide_string(void)
 	size_t wi = 0;
 	/* convert from multibyte to wide char */
 	(void)mbtowc(NULL, NULL, 0);
-	for (size_t i = 0; i < len; i += n, wi++) {
-		if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1)
+	for (size_t i = 0; i < buf.len; i += n, wi++) {
+		if ((n = mbtowc(&ws[wi], buf.data + i, MB_CUR_MAX)) == -1)
 			break;
 		if (n == 0)
 			n = 1;
 	}
-	free(s);
+	free(buf.data);
 	free(ws);
 
 	buffer *str = xcalloc(1, sizeof(*str));

Index: src/usr.bin/xlint/lint1/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.600 src/usr.bin/xlint/lint1/tree.c:1.601
--- src/usr.bin/xlint/lint1/tree.c:1.600	Thu Feb  1 18:37:06 2024
+++ src/usr.bin/xlint/lint1/tree.c	Thu Feb  1 21:19:13 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.600 2024/02/01 18:37:06 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.601 2024/02/01 21:19:13 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.600 2024/02/01 18:37:06 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.601 2024/02/01 21:19:13 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -4699,7 +4699,9 @@ cat_strings(buffer *s1, buffer *s2)
 	}
 
 	if (s1->data != NULL) {
-		s1->data = xrealloc(s1->data, s1->len + s2->len + 1);
+		while (s1->len + s2->len + 1 > s1->cap)
+			s1->cap *= 2;
+		s1->data = xrealloc(s1->data, s1->cap);
 		memcpy(s1->data + s1->len, s2->data, s2->len + 1);
 		free(s2->data);
 	}

Reply via email to