constmap.c (2232B)
1 #include "constmap.h" 2 3 #include "alloc.h" 4 #include "case.h" 5 6 static constmap_hash hash(char *s, int len) 7 { 8 unsigned char ch; 9 constmap_hash h; 10 h = 5381; 11 while (len > 0) { 12 ch = *s++ - 'A'; 13 if (ch <= 'Z' - 'A') 14 ch += 'a' - 'A'; 15 h = ((h << 5) + h) ^ ch; 16 --len; 17 } 18 return h; 19 } 20 21 char *constmap(struct constmap *cm, char *s, int len) 22 { 23 constmap_hash h; 24 int pos; 25 h = hash(s, len); 26 pos = cm->first[h & cm->mask]; 27 while (pos != -1) { 28 if (h == cm->hash[pos]) 29 if (len == cm->inputlen[pos]) 30 if (!case_diffb(cm->input[pos], len, s)) 31 return cm->input[pos] + cm->inputlen[pos] + 1; 32 pos = cm->next[pos]; 33 } 34 return 0; 35 } 36 37 int constmap_init(struct constmap *cm, char *s, int len, int flagcolon) 38 { 39 int i; 40 int j; 41 int k; 42 int pos; 43 constmap_hash h; 44 45 cm->num = 0; 46 for (j = 0; j < len; ++j) 47 if (!s[j]) 48 ++cm->num; 49 50 h = 64; 51 while (h && (h < cm->num)) 52 h += h; 53 cm->mask = h - 1; 54 55 cm->first = (int *)alloc(sizeof(int) * h); 56 if (cm->first) { 57 cm->input = (char **)alloc(sizeof(char *) * cm->num); 58 if (cm->input) { 59 cm->inputlen = (int *)alloc(sizeof(int) * cm->num); 60 if (cm->inputlen) { 61 cm->hash = (constmap_hash *) alloc(sizeof(constmap_hash) * cm->num); 62 if (cm->hash) { 63 cm->next = (int *)alloc(sizeof(int) * cm->num); 64 if (cm->next) { 65 for (h = 0; h <= cm->mask; ++h) 66 cm->first[h] = -1; 67 pos = 0; 68 i = 0; 69 for (j = 0; j < len; ++j) 70 if (!s[j]) { 71 k = j - i; 72 if (flagcolon) { 73 for (k = i; k < j; ++k) 74 if (s[k] == ':') 75 break; 76 if (k >= j) { 77 i = j + 1; 78 continue; 79 } 80 k -= i; 81 } 82 cm->input[pos] = s + i; 83 cm->inputlen[pos] = k; 84 h = hash(s + i, k); 85 cm->hash[pos] = h; 86 h &= cm->mask; 87 cm->next[pos] = cm->first[h]; 88 cm->first[h] = pos; 89 ++pos; 90 i = j + 1; 91 } 92 return 1; 93 } 94 alloc_free(cm->hash); 95 } 96 alloc_free(cm->inputlen); 97 } 98 alloc_free(cm->input); 99 } 100 alloc_free(cm->first); 101 } 102 return 0; 103 } 104 105 void constmap_free(struct constmap *cm) 106 { 107 alloc_free(cm->next); 108 alloc_free(cm->hash); 109 alloc_free(cm->inputlen); 110 alloc_free(cm->input); 111 alloc_free(cm->first); 112 }