home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / COMMON / SAVESTR.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  2KB  |  110 lines

  1. /* Copyright 1988 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)savestr.c 2.2 7/3/92 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. #ifndef  NHASH
  26. #define  NHASH        509        /* hash table size (prime!) */
  27. #endif
  28.  
  29. typedef struct s_head {
  30.     struct s_head  *next;        /* next in hash list */
  31.     int  nl;            /* links count */
  32. }  S_HEAD;                /* followed by the string itself */
  33.  
  34. static S_HEAD  *stab[NHASH];
  35.  
  36. static int  shash();
  37.  
  38. extern char  *savestr(), *strcpy(), *malloc();
  39.  
  40. #define  NULL        0
  41.  
  42. #define  string(sp)    ((char *)((sp)+1))
  43.  
  44. #define  salloc(str)    (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
  45.  
  46. #define  sfree(sp)    free((char *)(sp))
  47.  
  48.  
  49. char *
  50. savestr(str)                /* save a string */
  51. char  *str;
  52. {
  53.     register int  hval;
  54.     register S_HEAD  *sp;
  55.  
  56.     if (str == NULL)
  57.         return(NULL);
  58.     hval = shash(str);
  59.     for (sp = stab[hval]; sp != NULL; sp = sp->next)
  60.         if (!strcmp(str, string(sp))) {
  61.             sp->nl++;
  62.             return(string(sp));
  63.         }
  64.     if ((sp = salloc(str)) == NULL) {
  65.         eputs("Out of memory in savestr\n");
  66.         quit(1);
  67.     }
  68.     strcpy(string(sp), str);
  69.     sp->nl = 1;
  70.     sp->next = stab[hval];
  71.     stab[hval] = sp;
  72.     return(string(sp));
  73. }
  74.  
  75.  
  76. freestr(s)                /* free a string */
  77. char  *s;
  78. {
  79.     int  hval;
  80.     register S_HEAD  *spl, *sp;
  81.  
  82.     if (s == NULL)
  83.         return;
  84.     hval = shash(s);
  85.     for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
  86.         if (s == string(sp)) {
  87.             if (--sp->nl > 0)
  88.                 return;
  89.             if (spl != NULL)
  90.                 spl->next = sp->next;
  91.             else
  92.                 stab[hval] = sp->next;
  93.             sfree(sp);
  94.             return;
  95.         }
  96. }
  97.  
  98.  
  99. static int
  100. shash(s)                /* hash a string */
  101. register char  *s;
  102. {
  103.     register int  h = 0;
  104.  
  105.     while (*s)
  106.         h += *s++;
  107.  
  108.     return(h % NHASH);
  109. }
  110.