shithub: neatroff

Download patch

ref: ced19dc8c75fc6adfcbea9a46f65bd38ddfef512
parent: af5f4e16da8242be88bd1cfdd241ec54264e737c
author: Ali Gholami Rudi <[email protected]>
date: Sat Aug 3 16:18:16 EDT 2013

map: use starting character lists for keys[]

--- a/map.c
+++ b/map.c
@@ -2,20 +2,36 @@
 #include <string.h>
 #include "roff.h"
 
+/* register, macro, or environments names with more than two characters */
 static char keys[NREGS][GNLEN];
-static int nkeys;
+static int nkeys = 1;
+/* per starting character name lists */
+static int key_head[256];
+static int key_next[NREGS];
 
+/* return the index of s in keys[]; insert it if not in keys[] */
+static int key_get(char *s)
+{
+	int head = (unsigned char) s[0];
+	int i = key_head[head];
+	while (i > 0) {
+		if (!strcmp(keys[i], s))
+			return i;
+		i = key_next[i];
+	}
+	i = nkeys++;
+	strcpy(keys[i], s);
+	key_next[i] = key_head[head];
+	key_head[head] = i;
+	return i;
+}
+
 /* map register names to [0..NREGS * 2) */
 int map(char *s)
 {
-	int i;
 	if (n_cp || !s[1] || !s[2])
 		return REG(s[0], s[1]);
-	for (i = 0; i < nkeys; i++)
-		if (keys[i][0] == s[0] && !strcmp(keys[i], s))
-			return NREGS + i;
-	strcpy(keys[nkeys++], s);
-	return NREGS + nkeys - 1;
+	return NREGS + key_get(s);
 }
 
 /* returns a static buffer */