util.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "all.h"
  2. void*
  3. erealloc(void *a, int n)
  4. {
  5. a = realloc(a, n);
  6. if(a==nil)
  7. sysfatal("realloc: %r");
  8. return a;
  9. }
  10. char*
  11. estrdup(char *s)
  12. {
  13. s = strdup(s);
  14. if(s == nil)
  15. sysfatal("strdup: %r");
  16. return s;
  17. }
  18. void*
  19. emalloc(int n)
  20. {
  21. void *a;
  22. a = mallocz(n, 1);
  23. if(a == nil)
  24. sysfatal("malloc: %r");
  25. return a;
  26. }
  27. /*
  28. * Custom allocators to avoid malloc overheads on small objects.
  29. * We never free these. (See below.)
  30. */
  31. typedef struct Stringtab Stringtab;
  32. struct Stringtab {
  33. Stringtab *link;
  34. char *str;
  35. };
  36. static Stringtab*
  37. taballoc(void)
  38. {
  39. static Stringtab *t;
  40. static uint nt;
  41. if(nt == 0){
  42. t = malloc(64*sizeof(Stringtab));
  43. if(t == 0)
  44. sysfatal("out of memory");
  45. nt = 64;
  46. }
  47. nt--;
  48. return t++;
  49. }
  50. static char*
  51. xstrdup(char *s)
  52. {
  53. char *r;
  54. int len;
  55. static char *t;
  56. static int nt;
  57. len = strlen(s)+1;
  58. if(len >= 8192)
  59. sysfatal("strdup big string");
  60. if(nt < len){
  61. t = malloc(8192);
  62. if(t == 0)
  63. sysfatal("out of memory");
  64. nt = 8192;
  65. }
  66. r = t;
  67. t += len;
  68. nt -= len;
  69. strcpy(r, s);
  70. return r;
  71. }
  72. /*
  73. * Return a uniquely allocated copy of a string.
  74. * Don't free these -- they stay in the table for the
  75. * next caller who wants that particular string.
  76. * String comparison can be done with pointer comparison
  77. * if you know both strings are atoms.
  78. */
  79. static Stringtab *stab[1024];
  80. static uint
  81. hash(char *s)
  82. {
  83. uint h;
  84. uchar *p;
  85. h = 0;
  86. for(p=(uchar*)s; *p; p++)
  87. h = h*37 + *p;
  88. return h;
  89. }
  90. char*
  91. atom(char *str)
  92. {
  93. uint h;
  94. Stringtab *tab;
  95. h = hash(str) % nelem(stab);
  96. for(tab=stab[h]; tab; tab=tab->link)
  97. if(strcmp(str, tab->str) == 0)
  98. return tab->str;
  99. tab = taballoc();
  100. tab->str = xstrdup(str);
  101. tab->link = stab[h];
  102. stab[h] = tab;
  103. return tab->str;
  104. }
  105. char*
  106. unroot(char *path, char *root)
  107. {
  108. int len;
  109. char *s;
  110. len = strlen(root);
  111. while(len >= 1 && root[len-1]=='/')
  112. len--;
  113. if(strncmp(path, root, len)==0 && (path[len]=='/' || path[len]=='\0')){
  114. s = path+len;
  115. while(*s == '/')
  116. s++;
  117. return s;
  118. }
  119. return path;
  120. }