home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / icon / dos / src / common / strtbl.c < prev    next >
C/C++ Source or Header  |  1992-02-10  |  3KB  |  156 lines

  1. /*
  2.  * The functions in this file maintain a hash table of strings and manage
  3.  *   string buffers.
  4.  */
  5. #include "../h/gsupport.h"
  6.  
  7. /*
  8.  * Prototype for static function.
  9.  */
  10. hidden int streq  Params((int len,char *s1,char *s2));
  11.  
  12. struct str_entry {
  13.    char *s;
  14.    int length;
  15.    struct str_entry *next;
  16.    };
  17.  
  18. #define SBufSize 1024
  19. #define StrTblSz 149
  20. static struct str_entry *str_tbl[StrTblSz];
  21.  
  22. /*
  23.  * init_str - initialize string hash table.
  24.  */
  25. novalue init_str()
  26.    {
  27.    static int first_time = 1;
  28.    int h;
  29.  
  30.    if (first_time)
  31.       first_time = 0;
  32.    else
  33.       return;
  34.  
  35.    for (h = 0; h < StrTblSz; ++h)
  36.       str_tbl[h] = NULL;
  37.    }
  38.  
  39. /*
  40.  * init_sbuf - initialize a new sbuf struct, allocating an initial buffer.
  41.  */
  42. novalue init_sbuf(sbuf)
  43. struct str_buf *sbuf;
  44.    {
  45.    sbuf->size = SBufSize;
  46.    sbuf->strtimage = (char *)alloc((unsigned)SBufSize);
  47.    sbuf->endimage = sbuf->strtimage;
  48.    sbuf->end = sbuf->strtimage + SBufSize;
  49.    }
  50.  
  51. /*
  52.  * new_sbuf - allocate a new buffer for a sbuf struct, copying the partially
  53.  *   created string from the full buffer to the new one.
  54.  */
  55. novalue new_sbuf(sbuf)
  56. struct str_buf *sbuf;
  57.    {
  58.    char *s1, *s2;
  59.  
  60. #if IntBits == 16
  61.    unsigned int oldsize = sbuf->size;
  62.    sbuf->size += (sbuf->size/2);
  63.    if (sbuf->size < oldsize) {        /* check for overflow */
  64.       sbuf->size = MaxBlock;
  65.       }
  66. #else                    /* IntBits == 16 */
  67.    sbuf->size *= 2;
  68. #endif                    /* IntBits == 16 */
  69.    s1 = sbuf->strtimage;
  70.    sbuf->strtimage = (char *)alloc((unsigned)sbuf->size);
  71.    s2 = sbuf->strtimage;
  72.    while (s1 < sbuf->endimage)
  73.       *s2++ = *s1++;
  74.    sbuf->endimage = s2;
  75.    sbuf->end = sbuf->strtimage + sbuf->size;
  76.    }
  77.  
  78. /*
  79.  * spec_str - install a special string in the string table.
  80.  */
  81. char *spec_str(s)
  82. char *s;
  83.    {
  84.    struct str_entry *se;
  85.    register char *s1;
  86.    register int l;
  87.    register int h;
  88.  
  89.    h = 0;
  90.    l = 1;
  91.    for (s1 = s; *s1 != '\0'; ++s1) {
  92.      h += *s1 & 0377;
  93.      ++l;
  94.      }
  95.    h %= StrTblSz;
  96.    for (se = str_tbl[h]; se != NULL; se = se->next) 
  97.       if (l == se->length && streq(l, s, se->s))
  98.          return se->s;
  99.    se = NewStruct(str_entry);
  100.    se->s = s;
  101.    se->length = l;
  102.    se->next = str_tbl[h];
  103.    str_tbl[h] = se;
  104.    return s;
  105.    }
  106.  
  107. /*
  108.  * str_install - find out if the string in the buffer is in the string table.
  109.  *   If not, put it there. Return a pointer to the string in the table.
  110.  */
  111. char *str_install(sbuf)
  112. struct str_buf *sbuf;
  113.    {
  114.    int h;
  115.    struct str_entry *se;
  116.    register char *s;
  117.    register char *e;
  118.    int l;
  119.  
  120.    AppChar(*sbuf, '\0')
  121.    s = sbuf->strtimage;
  122.    e = sbuf->endimage;
  123.    h = 0;
  124.    while (s < e)
  125.      h += *s++ & 0377;
  126.    h %= StrTblSz;
  127.    s = sbuf->strtimage;
  128.    l = e - s;
  129.    for (se = str_tbl[h]; se != NULL; se = se->next) 
  130.       if (l == se->length && streq(l, s, se->s)) {
  131.          sbuf->endimage = s;
  132.          return se->s;
  133.          }
  134.    se = NewStruct(str_entry);
  135.    se->s = s;
  136.    se->length = l;
  137.    sbuf->strtimage = e;
  138.    se->next = str_tbl[h];
  139.    str_tbl[h] = se;
  140.    return se->s;
  141.    }
  142.  
  143. /*
  144.  * streq - compare s1 with s2 for len bytes, and return 1 for equal,
  145.  *  0 for not equal.
  146.  */
  147. static int streq(len, s1, s2)
  148. register int len;
  149. register char *s1, *s2;
  150.    {
  151.    while (len--)
  152.       if (*s1++ != *s2++)
  153.          return 0;
  154.    return 1;
  155.    }
  156.