string.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "all.h"
  2. #define STRHASH 509 /* prime */
  3. static Strnode * stab[STRHASH];
  4. static long hashfun(void*);
  5. static Strnode* nalloc(int);
  6. char *
  7. strfind(char *a)
  8. {
  9. Strnode **bin, *x, *xp;
  10. bin = &stab[hashfun(a) % STRHASH];
  11. for(xp=0, x=*bin; x; xp=x, x=x->next)
  12. if(x->str[0] == a[0] && strcmp(x->str, a) == 0)
  13. break;
  14. if(x == 0)
  15. return 0;
  16. if(xp){
  17. xp->next = x->next;
  18. x->next = *bin;
  19. *bin = x;
  20. }
  21. return x->str;
  22. }
  23. char *
  24. strstore(char *a)
  25. {
  26. Strnode **bin, *x, *xp;
  27. int n;
  28. bin = &stab[hashfun(a) % STRHASH];
  29. for(xp=0, x=*bin; x; xp=x, x=x->next)
  30. if(x->str[0] == a[0] && strcmp(x->str, a) == 0)
  31. break;
  32. if(x == 0){
  33. n = strlen(a)+1;
  34. x = nalloc(n);
  35. memmove(x->str, a, n);
  36. x->next = *bin;
  37. *bin = x;
  38. }else if(xp){
  39. xp->next = x->next;
  40. x->next = *bin;
  41. *bin = x;
  42. }
  43. return x->str;
  44. }
  45. void
  46. strprint(int fd)
  47. {
  48. Strnode **bin, *x;
  49. for(bin = stab; bin < stab+STRHASH; bin++)
  50. for(x=*bin; x; x=x->next)
  51. fprint(fd, "%ld %s\n", bin-stab, x->str);
  52. }
  53. static long
  54. hashfun(void *v)
  55. {
  56. ulong a = 0, b;
  57. uchar *s = v;
  58. while(*s){
  59. a = (a << 4) + *s++;
  60. if(b = a&0xf0000000){ /* assign = */
  61. a ^= b >> 24;
  62. a ^= b;
  63. }
  64. }
  65. return a;
  66. }
  67. #define STRSIZE 1000
  68. static Strnode *
  69. nalloc(int n) /* get permanent storage for Strnode */
  70. {
  71. static char *curstp;
  72. static int nchleft;
  73. int k;
  74. char *p;
  75. if(n < 4)
  76. n = 4;
  77. else if(k = n&3) /* assign = */
  78. n += 4-k;
  79. n += sizeof(Strnode)-4;
  80. if(n > nchleft){
  81. nchleft = STRSIZE;
  82. while(nchleft < n)
  83. nchleft *= 2;
  84. if((curstp = malloc(nchleft)) == 0)
  85. panic("malloc(%d) failed in nalloc\n", nchleft);
  86. }
  87. p = curstp;
  88. curstp += n;
  89. nchleft -= n;
  90. return (Strnode*)p;
  91. }