diff options
| author | manuel <manuel@mausz.at> | 2013-02-04 00:08:53 +0100 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2013-02-04 00:08:53 +0100 |
| commit | 69aec538b456402170dc723af417ba5c05389c32 (patch) | |
| tree | e6f34c543f17c6392447ea337b2e2868212424d1 /constmap.c | |
| download | qmail-69aec538b456402170dc723af417ba5c05389c32.tar.gz qmail-69aec538b456402170dc723af417ba5c05389c32.tar.bz2 qmail-69aec538b456402170dc723af417ba5c05389c32.zip | |
qmail 1.03 import
Diffstat (limited to 'constmap.c')
| -rw-r--r-- | constmap.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/constmap.c b/constmap.c new file mode 100644 index 0000000..722e3b8 --- /dev/null +++ b/constmap.c | |||
| @@ -0,0 +1,114 @@ | |||
| 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 | } | ||
