Import ezmlm-idx 0.40
[ezmlm] / constmap.c
1 #include "constmap.h"
2 #include "alloc.h"
3 #include "case.h"
4
5 static constmap_hash hash(s,len)
6 char *s;
7 int len;
8 {
9 unsigned char ch;
10 constmap_hash h;
11 h = 5381;
12 while (len > 0) {
13 ch = *s++ - 'A';
14 if (ch <= 'Z' - 'A') ch += 'a' - 'A';
15 h = ((h << 5) + h) ^ ch;
16 --len;
17 }
18 return h;
19 }
20
21 /* Returns index of string in constmap. 1 = first string, 2 = second ... */
22 /* 0 not found. Use for commands */
23 int constmap_index(cm,s,len)
24 struct constmap *cm;
25 char *s;
26 int len;
27 {
28 constmap_hash h;
29 int pos;
30 h = hash(s,len);
31 pos = cm->first[h & cm->mask];
32 while (pos != -1) {
33 if (h == cm->hash[pos])
34 if (len == cm->inputlen[pos])
35 if (!case_diffb(cm->input[pos],len,s))
36 return pos + 1;
37 pos = cm->next[pos];
38 }
39 return 0;
40 }
41
42 /* returns pointer to sz of string with index "idx". 1 = first, 2 = second...*/
43 char *constmap_get(cm,idx)
44 struct constmap *cm;
45 int idx;
46
47 {
48 if (idx <= 0 || idx > cm->num)
49 return 0;
50 else
51 return cm->input[idx-1];
52 }
53
54 char *constmap(cm,s,len)
55 struct constmap *cm;
56 char *s;
57 int len;
58 {
59 constmap_hash h;
60 int pos;
61 h = hash(s,len);
62 pos = cm->first[h & cm->mask];
63 while (pos != -1) {
64 if (h == cm->hash[pos])
65 if (len == cm->inputlen[pos])
66 if (!case_diffb(cm->input[pos],len,s))
67 return cm->input[pos] + cm->inputlen[pos] + 1;
68 pos = cm->next[pos];
69 }
70 return 0;
71 }
72
73 int constmap_init(cm,s,len,flagcolon)
74 /* if flagcolon is true, we process only the stuff before the colon on */
75 /* each line. Otherwise, it's the entire line. Still, the entire line */
76 /* is stored! */
77 struct constmap *cm;
78 char *s;
79 int len;
80 int flagcolon;
81 {
82 int i;
83 int j;
84 int k;
85 int pos;
86 constmap_hash h;
87
88 cm->num = 0;
89 for (j = 0;j < len;++j) if (!s[j]) ++cm->num;
90
91 h = 64;
92 while (h && (h < cm->num)) h += h;
93 cm->mask = h - 1;
94
95 cm->first = (int *) alloc(sizeof(int) * h);
96 if (cm->first) {
97 cm->input = (char **) alloc(sizeof(char *) * cm->num);
98 if (cm->input) {
99 cm->inputlen = (int *) alloc(sizeof(int) * cm->num);
100 if (cm->inputlen) {
101 cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num);
102 if (cm->hash) {
103 cm->next = (int *) alloc(sizeof(int) * cm->num);
104 if (cm->next) {
105 for (h = 0;h <= cm->mask;++h)
106 cm->first[h] = -1;
107 pos = 0;
108 i = 0;
109 for (j = 0;j < len;++j)
110 if (!s[j]) {
111 k = j - i;
112 if (flagcolon) {
113 for (k = i;k < j;++k)
114 if (s[k] == ':')
115 break;
116 if (k >= j) { i = j + 1; continue; }
117 k -= i;
118 }
119 cm->input[pos] = s + i;
120 cm->inputlen[pos] = k;
121 h = hash(s + i,k);
122 cm->hash[pos] = h;
123 h &= cm->mask;
124 cm->next[pos] = cm->first[h];
125 cm->first[h] = pos;
126 ++pos;
127 i = j + 1;
128 }
129 return 1;
130 }
131 alloc_free(cm->hash);
132 }
133 alloc_free(cm->inputlen);
134 }
135 alloc_free(cm->input);
136 }
137 alloc_free(cm->first);
138 }
139 return 0;
140 }
141
142 void constmap_free(cm)
143 struct constmap *cm;
144 {
145 alloc_free(cm->next);
146 alloc_free(cm->hash);
147 alloc_free(cm->inputlen);
148 alloc_free(cm->input);
149 alloc_free(cm->first);
150 }