constmap.c
changeset 0 068428edee47
equal deleted inserted replaced
-1:000000000000 0:068428edee47
       
     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 }