Module Name:    src
Committed By:   rillig
Date:           Wed Jun 14 19:05:40 UTC 2023

Modified Files:
        src/tests/usr.bin/indent: t_errors.sh
        src/usr.bin/indent: indent.c indent.h parse.c

Log Message:
indent: allow more than 128 brace levels


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/tests/usr.bin/indent/t_errors.sh
cvs rdiff -u -r1.365 -r1.366 src/usr.bin/indent/indent.c
cvs rdiff -u -r1.195 -r1.196 src/usr.bin/indent/indent.h
cvs rdiff -u -r1.75 -r1.76 src/usr.bin/indent/parse.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/indent/t_errors.sh
diff -u src/tests/usr.bin/indent/t_errors.sh:1.36 src/tests/usr.bin/indent/t_errors.sh:1.37
--- src/tests/usr.bin/indent/t_errors.sh:1.36	Wed Jun 14 10:26:00 2023
+++ src/tests/usr.bin/indent/t_errors.sh	Wed Jun 14 19:05:40 2023
@@ -1,5 +1,5 @@
 #! /bin/sh
-# $NetBSD: t_errors.sh,v 1.36 2023/06/14 10:26:00 rillig Exp $
+# $NetBSD: t_errors.sh,v 1.37 2023/06/14 19:05:40 rillig Exp $
 #
 # Copyright (c) 2021 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -459,7 +459,7 @@ stack_overflow_body()
 
 	atf_check \
 	    -s 'exit:1' \
-	    -e 'inline:indent: Parser stack overflow\n' \
+	    -e 'inline:error: code.c:3: Stuff missing from end of file\n' \
 	    "$indent" code.c
 }
 

Index: src/usr.bin/indent/indent.c
diff -u src/usr.bin/indent/indent.c:1.365 src/usr.bin/indent/indent.c:1.366
--- src/usr.bin/indent/indent.c:1.365	Wed Jun 14 16:14:30 2023
+++ src/usr.bin/indent/indent.c	Wed Jun 14 19:05:40 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: indent.c,v 1.365 2023/06/14 16:14:30 rillig Exp $	*/
+/*	$NetBSD: indent.c,v 1.366 2023/06/14 19:05:40 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: indent.c,v 1.365 2023/06/14 16:14:30 rillig Exp $");
+__RCSID("$NetBSD: indent.c,v 1.366 2023/06/14 19:05:40 rillig Exp $");
 
 #include <sys/param.h>
 #include <err.h>
@@ -187,7 +187,7 @@ ind_add(int ind, const char *s, size_t l
 static void
 init_globals(void)
 {
-	ps.psyms.sym[ps.psyms.len++] = psym_stmt;
+	ps_push(psym_stmt, false);
 	ps.prev_lsym = lsym_semicolon;
 	ps.lbrace_kind = psym_lbrace_block;
 
@@ -454,36 +454,55 @@ paren_stack_push(struct paren_stack *s, 
 	s->item[s->len++] = (struct paren_level){indent, cast};
 }
 
+static void *
+dup_mem(const void *src, size_t size)
+{
+	return memcpy(nonnull(malloc(size)), src, size);
+}
+
+#define dup_array(src, len) \
+    dup_mem((src), sizeof((src)[0]) * (len))
+#define copy_array(dst, src, len) \
+    memcpy((dst), (src), sizeof((dst)[0]) * (len))
+
 static void
-parser_state_backup(struct parser_state *dst)
+parser_state_back_up(struct parser_state *dst)
 {
 	*dst = ps;
 
-	dst->paren.item = nonnull(
-	    malloc(sizeof(dst->paren.item[0]) * ps.paren.cap));
-	dst->paren.len = ps.paren.len;
-	dst->paren.cap = ps.paren.cap;
-	memcpy(dst->paren.item, ps.paren.item,
-	    sizeof(dst->paren.item[0]) * ps.paren.len);
+	dst->paren.item = dup_array(ps.paren.item, ps.paren.len);
+	dst->psyms.sym = dup_array(ps.psyms.sym, ps.psyms.len);
+	dst->psyms.ind_level = dup_array(ps.psyms.ind_level, ps.psyms.len);
 }
 
 static void
 parser_state_restore(const struct parser_state *src)
 {
-	struct paren_stack dst_paren = ps.paren;
+	struct paren_level *ps_paren_item = ps.paren.item;
+	size_t ps_paren_cap = ps.paren.cap;
+	enum parser_symbol *ps_psyms_sym = ps.psyms.sym;
+	int *ps_psyms_ind_level = ps.psyms.ind_level;
+	size_t ps_psyms_cap = ps.psyms.cap;
+
 	ps = *src;
-	ps.paren = dst_paren;
 
-	ps.paren.len = 0;
-	for (size_t i = 0; i < src->paren.len; i++)
-		paren_stack_push(&ps.paren,
-		    src->paren.item[i].indent, src->paren.item[i].cast);
+	ps.paren.item = ps_paren_item;
+	ps.paren.cap = ps_paren_cap;
+	ps.psyms.sym = ps_psyms_sym;
+	ps.psyms.ind_level = ps_psyms_ind_level;
+	ps.psyms.cap = ps_psyms_cap;
+
+	copy_array(ps.paren.item, src->paren.item, src->paren.len);
+	copy_array(ps.psyms.sym, src->psyms.sym, src->psyms.len);
+	copy_array(ps.psyms.ind_level, src->psyms.ind_level, src->psyms.len);
 }
 
 static void
 parser_state_free(struct parser_state *pst)
 {
 	free(pst->paren.item);
+	free(pst->psyms.sym);
+	free(pst->psyms.ind_level);
 }
 
 static void
@@ -507,7 +526,7 @@ process_preprocessing(void)
 			ifdef.item = nonnull(realloc(ifdef.item,
 				sizeof(ifdef.item[0]) * ifdef.cap));
 		}
-		parser_state_backup(ifdef.item + ifdef.len++);
+		parser_state_back_up(ifdef.item + ifdef.len++);
 		out.line_kind = lk_if;
 
 	} else if (dir_len >= 2 && memcmp(dir, "el", 2) == 0) {

Index: src/usr.bin/indent/indent.h
diff -u src/usr.bin/indent/indent.h:1.195 src/usr.bin/indent/indent.h:1.196
--- src/usr.bin/indent/indent.h:1.195	Wed Jun 14 16:14:30 2023
+++ src/usr.bin/indent/indent.h	Wed Jun 14 19:05:40 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: indent.h,v 1.195 2023/06/14 16:14:30 rillig Exp $	*/
+/*	$NetBSD: indent.h,v 1.196 2023/06/14 19:05:40 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -257,8 +257,6 @@ extern enum indent_enabled {
 	indent_last_off_line,
 } indent_enabled;
 
-#define	STACKSIZE 256
-
 /* Properties of each level of parentheses or brackets. */
 struct paren_level {
 	int indent;		/* indentation of the operand/argument,
@@ -272,12 +270,13 @@ struct paren_level {
 };
 
 struct psym_stack {
+	parser_symbol *sym;
+	int *ind_level;
 	size_t len;		/* points to one behind the top of the stack;
 				 * 1 at the top level of the file outside a
 				 * declaration or statement; 2 at the top
 				 * level */
-	parser_symbol sym[STACKSIZE];
-	int ind_level[STACKSIZE];
+	size_t cap;
 };
 
 /*
@@ -475,6 +474,7 @@ void parse(parser_symbol);
 void process_comment(void);
 void set_option(const char *, const char *);
 void load_profile_files(const char *);
+void ps_push(parser_symbol, bool);
 
 void *nonnull(void *);
 

Index: src/usr.bin/indent/parse.c
diff -u src/usr.bin/indent/parse.c:1.75 src/usr.bin/indent/parse.c:1.76
--- src/usr.bin/indent/parse.c:1.75	Wed Jun 14 17:52:45 2023
+++ src/usr.bin/indent/parse.c	Wed Jun 14 19:05:40 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.75 2023/06/14 17:52:45 rillig Exp $	*/
+/*	$NetBSD: parse.c,v 1.76 2023/06/14 19:05:40 rillig Exp $	*/
 
 /*-
  * SPDX-License-Identifier: BSD-4-Clause
@@ -38,9 +38,10 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: parse.c,v 1.75 2023/06/14 17:52:45 rillig Exp $");
+__RCSID("$NetBSD: parse.c,v 1.76 2023/06/14 19:05:40 rillig Exp $");
 
 #include <err.h>
+#include <stdlib.h>
 
 #include "indent.h"
 
@@ -98,12 +99,18 @@ decl_level(void)
 	return level;
 }
 
-static void
+void
 ps_push(parser_symbol psym, bool follow)
 {
-	if (ps.psyms.len >= STACKSIZE)
-		errx(1, "Parser stack overflow");
-	ps.psyms.sym[++ps.psyms.len - 1] = psym;
+	if (ps.psyms.len == ps.psyms.cap) {
+		ps.psyms.cap += 16;
+		ps.psyms.sym = nonnull(realloc(ps.psyms.sym,
+		    sizeof(ps.psyms.sym[0]) * ps.psyms.cap));
+		ps.psyms.ind_level = nonnull(realloc(ps.psyms.ind_level,
+		    sizeof(ps.psyms.ind_level[0]) * ps.psyms.cap));
+	}
+	ps.psyms.len++;
+	ps.psyms.sym[ps.psyms.len - 1] = psym;
 	ps.psyms.ind_level[ps.psyms.len - 1] =
 	    follow ? ps.ind_level_follow : ps.ind_level;
 }

Reply via email to