|
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 char *constmap(cm,s,len) |
|
22 struct constmap *cm; |
|
23 char *s; |
|
24 int len; |
|
25 { |
|
26 constmap_hash h; |
|
27 int pos; |
|
28 h = hash(s,len); |
|
29 pos = cm->first[h & cm->mask]; |
|
30 while (pos != -1) { |
|
31 if (h == cm->hash[pos]) |
|
32 if (len == cm->inputlen[pos]) |
|
33 if (!case_diffb(cm->input[pos],len,s)) |
|
34 return cm->input[pos] + cm->inputlen[pos] + 1; |
|
35 pos = cm->next[pos]; |
|
36 } |
|
37 return 0; |
|
38 } |
|
39 |
|
40 int constmap_init(cm,s,len,flagcolon) |
|
41 struct constmap *cm; |
|
42 char *s; |
|
43 int len; |
|
44 int flagcolon; |
|
45 { |
|
46 int i; |
|
47 int j; |
|
48 int k; |
|
49 int pos; |
|
50 constmap_hash h; |
|
51 |
|
52 cm->num = 0; |
|
53 for (j = 0;j < len;++j) if (!s[j]) ++cm->num; |
|
54 |
|
55 h = 64; |
|
56 while (h && (h < cm->num)) h += h; |
|
57 cm->mask = h - 1; |
|
58 |
|
59 cm->first = (int *) alloc(sizeof(int) * h); |
|
60 if (cm->first) { |
|
61 cm->input = (char **) alloc(sizeof(char *) * cm->num); |
|
62 if (cm->input) { |
|
63 cm->inputlen = (int *) alloc(sizeof(int) * cm->num); |
|
64 if (cm->inputlen) { |
|
65 cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num); |
|
66 if (cm->hash) { |
|
67 cm->next = (int *) alloc(sizeof(int) * cm->num); |
|
68 if (cm->next) { |
|
69 for (h = 0;h <= cm->mask;++h) |
|
70 cm->first[h] = -1; |
|
71 pos = 0; |
|
72 i = 0; |
|
73 for (j = 0;j < len;++j) |
|
74 if (!s[j]) { |
|
75 k = j - i; |
|
76 if (flagcolon) { |
|
77 for (k = i;k < j;++k) |
|
78 if (s[k] == ':') |
|
79 break; |
|
80 if (k >= j) { i = j + 1; continue; } |
|
81 k -= i; |
|
82 } |
|
83 cm->input[pos] = s + i; |
|
84 cm->inputlen[pos] = k; |
|
85 h = hash(s + i,k); |
|
86 cm->hash[pos] = h; |
|
87 h &= cm->mask; |
|
88 cm->next[pos] = cm->first[h]; |
|
89 cm->first[h] = pos; |
|
90 ++pos; |
|
91 i = j + 1; |
|
92 } |
|
93 return 1; |
|
94 } |
|
95 alloc_free(cm->hash); |
|
96 } |
|
97 alloc_free(cm->inputlen); |
|
98 } |
|
99 alloc_free(cm->input); |
|
100 } |
|
101 alloc_free(cm->first); |
|
102 } |
|
103 return 0; |
|
104 } |
|
105 |
|
106 void constmap_free(cm) |
|
107 struct constmap *cm; |
|
108 { |
|
109 alloc_free(cm->next); |
|
110 alloc_free(cm->hash); |
|
111 alloc_free(cm->inputlen); |
|
112 alloc_free(cm->input); |
|
113 alloc_free(cm->first); |
|
114 } |