/usr.bin/xlint/lint2/hash.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 166 lines · 90 code · 24 blank · 52 comment · 24 complexity · 5cfd2dbcab0e7d48d2e7d09f7c756ca6 MD5 · raw file

  1. /* $NetBSD: hash.c,v 1.7 2002/01/21 19:49:52 tv Exp $ */
  2. /*
  3. * Copyright (c) 1994, 1995 Jochen Pohl
  4. * All Rights Reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. All advertising materials mentioning features or use of this software
  15. * must display the following acknowledgement:
  16. * This product includes software developed by Jochen Pohl for
  17. * The NetBSD Project.
  18. * 4. The name of the author may not be used to endorse or promote products
  19. * derived from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  22. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  23. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  24. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  26. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  30. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #include <sys/cdefs.h>
  33. #if defined(__RCSID) && !defined(lint)
  34. __RCSID("$NetBSD: hash.c,v 1.7 2002/01/21 19:49:52 tv Exp $");
  35. #endif
  36. __FBSDID("$FreeBSD$");
  37. /*
  38. * XXX Really need a generalized hash table package
  39. */
  40. #include <err.h>
  41. #include <limits.h>
  42. #include <stddef.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include "lint2.h"
  46. /* pointer to hash table, initialized in inithash() */
  47. static hte_t **htab;
  48. static int hash(const char *);
  49. /*
  50. * Initialize hash table.
  51. */
  52. void
  53. _inithash(hte_t ***tablep)
  54. {
  55. if (tablep == NULL)
  56. tablep = &htab;
  57. *tablep = xcalloc(HSHSIZ2, sizeof (hte_t *));
  58. }
  59. /*
  60. * Compute hash value from a string.
  61. */
  62. static int
  63. hash(const char *s)
  64. {
  65. u_int v;
  66. const u_char *us;
  67. v = 0;
  68. for (us = (const u_char *)s; *us != '\0'; us++) {
  69. v = (v << sizeof (v)) + *us;
  70. v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v));
  71. }
  72. return (v % HSHSIZ2);
  73. }
  74. /*
  75. * Look for a hash table entry. If no hash table entry for the
  76. * given name exists and mknew is set, create a new one.
  77. */
  78. hte_t *
  79. _hsearch(hte_t **table, const char *s, int mknew)
  80. {
  81. int h;
  82. hte_t *hte;
  83. if (table == NULL)
  84. table = htab;
  85. h = hash(s);
  86. for (hte = table[h]; hte != NULL; hte = hte->h_link) {
  87. if (strcmp(hte->h_name, s) == 0)
  88. break;
  89. }
  90. if (hte != NULL || !mknew)
  91. return (hte);
  92. /* create a new hte */
  93. hte = xmalloc(sizeof (hte_t));
  94. hte->h_name = xstrdup(s);
  95. hte->h_used = 0;
  96. hte->h_def = 0;
  97. hte->h_static = 0;
  98. hte->h_syms = NULL;
  99. hte->h_lsym = &hte->h_syms;
  100. hte->h_calls = NULL;
  101. hte->h_lcall = &hte->h_calls;
  102. hte->h_usyms = NULL;
  103. hte->h_lusym = &hte->h_usyms;
  104. hte->h_link = table[h];
  105. hte->h_hte = NULL;
  106. table[h] = hte;
  107. return (hte);
  108. }
  109. /*
  110. * Call function f for each name in the hash table.
  111. */
  112. void
  113. _forall(hte_t **table, void (*f)(hte_t *))
  114. {
  115. int i;
  116. hte_t *hte;
  117. if (table == NULL)
  118. table = htab;
  119. for (i = 0; i < HSHSIZ2; i++) {
  120. for (hte = table[i]; hte != NULL; hte = hte->h_link)
  121. (*f)(hte);
  122. }
  123. }
  124. /*
  125. * Free all contents of the hash table that this module allocated.
  126. */
  127. void
  128. _destroyhash(hte_t **table)
  129. {
  130. int i;
  131. hte_t *hte, *nexthte;
  132. if (table == NULL)
  133. err(1, "_destroyhash called on main hash table");
  134. for (i = 0; i < HSHSIZ2; i++) {
  135. for (hte = table[i]; hte != NULL; hte = nexthte) {
  136. free((void *)hte->h_name);
  137. nexthte = hte->h_link;
  138. free(hte);
  139. }
  140. }
  141. free(table);
  142. }