home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / formats / ttddd / spec / t3d_doc / igensurf.zoo / src / savestr.c < prev   
C/C++ Source or Header  |  1991-09-25  |  2KB  |  123 lines

  1. /* Copyright 1988 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)savestr.c 1.2 2/2/89 LBL";
  5. #endif
  6.  
  7. /*
  8.  *  savestr.c - routines for efficient string storage.
  9.  *
  10.  *    Savestr(s) stores a shared read-only string.
  11.  *  Freestr(s) indicates a client is finished with a string.
  12.  *    All strings must be null-terminated.  There is
  13.  *  no imposed length limit.
  14.  *    Strings stored with savestr(s) can be equated
  15.  *  reliably using their pointer values.  A tailored version
  16.  *  of strcmp(s1,s2) is included.
  17.  *    Calls to savestr(s) and freestr(s) should be
  18.  *  balanced (obviously).  The last call to freestr(s)
  19.  *  frees memory associated with the string; it should
  20.  *  never be referenced again.
  21.  *
  22.  *     5/14/87
  23.  */
  24.  
  25. #include <stdio.h>
  26.  
  27. #ifndef  NHASH
  28. #define  NHASH        509        /* hash table size (prime!) */
  29. #endif
  30.  
  31. typedef struct s_head {
  32.     struct s_head  *next;        /* next in hash list */
  33.     int  nl;            /* links count */
  34. }  S_HEAD;                /* followed by the string itself */
  35.  
  36. static S_HEAD  *stab[NHASH];
  37.  
  38. extern char  *savestr(), *strcpy(), *malloc();
  39.  
  40. #define  string(sp)    ((char *)((sp)+1))
  41.  
  42. #define  salloc(str)    (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
  43.  
  44. #define  sfree(sp)    free((char *)(sp))
  45.  
  46.  
  47. char *
  48. savestr(str)                /* save a string */
  49. char  *str;
  50. {
  51.     register int  hval;
  52.     register S_HEAD  *sp;
  53.  
  54.     if (str == NULL)
  55.         return(NULL);
  56.     hval = shash(str);
  57.     for (sp = stab[hval]; sp != NULL; sp = sp->next)
  58.         if (!strcmp(str, string(sp))) {
  59.             sp->nl++;
  60.             return(string(sp));
  61.         }
  62.     if ((sp = salloc(str)) == NULL) {
  63.         fprintf(stderr, "Out of memory in savestr\n");
  64.         exit(1);
  65.     }
  66.     strcpy(string(sp), str);
  67.     sp->nl = 1;
  68.     sp->next = stab[hval];
  69.     stab[hval] = sp;
  70.     return(string(sp));
  71. }
  72.  
  73.  
  74. freestr(s)                /* free a string */
  75. char  *s;
  76. {
  77.     int  hval;
  78.     register S_HEAD  *spl, *sp;
  79.  
  80.     if (s == NULL)
  81.         return;
  82.     hval = shash(s);
  83.     for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
  84.         if (s == string(sp)) {
  85.             if (--sp->nl > 0)
  86.                 return;
  87.             if (spl != NULL)
  88.                 spl->next = sp->next;
  89.             else
  90.                 stab[hval] = sp->next;
  91.             sfree(sp);
  92.             return;
  93.         }
  94. }
  95.  
  96.  
  97. int
  98. strcmp(s1, s2)                /* check for s1==s2 */
  99. register char  *s1, *s2;
  100. {
  101.     if (s1 == s2)
  102.         return(0);
  103.  
  104.     while (*s1 == *s2++)
  105.         if (!*s1++)
  106.             return(0);
  107.  
  108.     return(*s1 - *--s2);
  109. }
  110.  
  111.  
  112. static int
  113. shash(s)                /* hash a string */
  114. register char  *s;
  115. {
  116.     register int  h = 0;
  117.  
  118.     while (*s)
  119.         h += *s++;
  120.  
  121.     return(h % NHASH);
  122. }
  123.