ref: ced19dc8c75fc6adfcbea9a46f65bd38ddfef512
parent: af5f4e16da8242be88bd1cfdd241ec54264e737c
author: Ali Gholami Rudi <ali@rudi.ir>
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 */