shithub: trueawk

Download patch

ref: fa355f3eb97cdd89a525d61e4b4118a27fff26f7
parent: e7ad51dc32aa7b61dfce903c82c82f75b93bfae7
author: Arnold D. Robbins <arnold@skeeve.com>
date: Wed Oct 11 05:01:04 EDT 2023

Track inuse vs. allocated, use bsearch in set_gototab.

--- a/awk.h
+++ b/awk.h
@@ -251,6 +251,7 @@
 
 typedef struct gtt {	/* gototab */
 	size_t	allocated;
+	size_t	inuse;
 	gtte	*entries;
 } gtt;
 
--- a/b.c
+++ b/b.c
@@ -172,6 +172,7 @@
 		if (f->gototab[i].entries == NULL)
 			goto out;
 		f->gototab[i].allocated = NCHARS;
+		f->gototab[i].inuse = 0;
 		f->out[i] = 0;
 		f->posns[i] = NULL;
 	}
@@ -268,7 +269,7 @@
 	}
 	if ((f->posns[2])[1] == f->accept)
 		f->out[2] = 1;
-	for (i = 0; i < f->gototab[2].allocated; i++)
+	for (i = 0; i < f->gototab[2].inuse; i++)
 		set_gototab(f, 2, 0, 0); /* f->gototab[2][i] = 0; */
 	f->curstat = cgoto(f, 2, HAT);
 	if (anchor) {
@@ -597,17 +598,6 @@
 
 static int get_gototab(fa *f, int state, int ch) /* hide gototab inplementation */
 {
-#if 0
-	int i;
-	for (i = 0; i < f->gototab[state].allocated; i++) {
-		if (f->gototab[state].entries[i].ch == 0)
-			break;
-		if (f->gototab[state].entries[i].ch == ch)
-			return f->gototab[state].entries[i].state;
-	}
-	return 0;
-#else
-
 	gtte key;
 	gtte *item;
 
@@ -614,7 +604,7 @@
 	key.ch = ch;
 	key.state = 0;	/* irrelevant */
 	item = bsearch(& key, f->gototab[state].entries,
-			f->gototab[state].allocated, sizeof(gtte),
+			f->gototab[state].inuse, sizeof(gtte),
 			entry_cmp);
 
 	if (item == NULL)
@@ -621,7 +611,6 @@
 		return 0;
 	else
 		return item->state;
-#endif
 }
 
 static int entry_cmp(const void *l, const void *r)
@@ -636,8 +625,8 @@
 
 static int set_gototab(fa *f, int state, int ch, int val) /* hide gototab inplementation */
 {
+#if 0
 	int i;
-	gtte *p;
 	for (i = 0; i < f->gototab[state].allocated; i++) {
 		if (f->gototab[state].entries[i].ch == 0 || f->gototab[state].entries[i].ch == ch) {
 			f->gototab[state].entries[i].ch = ch;
@@ -645,15 +634,36 @@
 			return val;
 		}
 	}
-	p = realloc(f->gototab[state].entries, ++(f->gototab[state].allocated) * sizeof(gtte));
-	if (p == NULL)
-		overflo(__func__);
+#else
+	gtte key;
+	gtte *item, *p;
 
-	f->gototab[state].entries = p;
-	f->gototab[state].entries[i].ch = ch;
-	f->gototab[state].entries[i].state = val;
+	key.ch = ch;
+	key.state = 0;	/* irrelevant */
+	item = bsearch(& key, f->gototab[state].entries,
+			f->gototab[state].inuse, sizeof(gtte),
+			entry_cmp);
 
-	qsort(p, f->gototab[state].allocated, sizeof(gtte), entry_cmp);
+	if (item != NULL) {
+		item->state = state;
+		return item->state;
+	}
+#endif
+	gtt *tab = & f->gototab[state];
+	if (tab->inuse + 1 >= tab->allocated) {
+		size_t new_size = tab->allocated * 2;
+		p = realloc(f->gototab[state].entries, new_size * sizeof(gtte));
+		if (p == NULL)
+			overflo(__func__);
+		f->gototab[state].allocated = new_size;
+		f->gototab[state].entries = p;
+	}
+	++tab->inuse;
+	f->gototab[state].entries[tab->inuse].ch = ch;
+	f->gototab[state].entries[tab->inuse].state = val;
+
+	qsort(f->gototab[state].entries,
+		f->gototab[state].inuse, sizeof(gtte), entry_cmp);
 
 	return val; /* not used anywhere at the moment */
 }
--