stringmap.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * stringmap.c: sucky implementation of binary trees
  3. *
  4. * This makes no attempt to balance the tree, so has bad worst-case behaviour.
  5. * Also, I haven't implemented removal of items from the tree. So sue me.
  6. *
  7. * Copyright (c) 2001 Chris Lightfoot. All rights reserved.
  8. *
  9. */
  10. static const char rcsid[] = "$Id: stringmap.c,v 1.4 2010/11/27 11:06:12 pdw Exp $";
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "stringmap.h"
  14. #include "vector.h"
  15. #include "iftop.h"
  16. /* stringmap_new:
  17. * Allocate memory for a new stringmap. */
  18. stringmap stringmap_new() {
  19. stringmap S;
  20. S = xcalloc(sizeof *S, 1);
  21. return S;
  22. }
  23. /* stringmap_delete:
  24. * Free memory for a stringmap. */
  25. void stringmap_delete(stringmap S) {
  26. if (!S) return;
  27. if (S->l) stringmap_delete(S->l);
  28. if (S->g) stringmap_delete(S->g);
  29. xfree(S->key);
  30. xfree(S);
  31. }
  32. /* stringmap_delete_free:
  33. * Free memory for a stringmap, and the objects contained in it, assuming that
  34. * they are pointers to memory allocated by xmalloc(3). */
  35. void stringmap_delete_free(stringmap S) {
  36. if (!S) return;
  37. if (S->l) stringmap_delete_free(S->l);
  38. if (S->g) stringmap_delete_free(S->g);
  39. xfree(S->key);
  40. xfree(S->d.v);
  41. xfree(S);
  42. }
  43. /* stringmap_insert:
  44. * Insert into S an item having key k and value d. Returns a pointer to
  45. * the existing item value, or NULL if a new item was created.
  46. */
  47. item *stringmap_insert(stringmap S, const char *k, const item d) {
  48. if (!S) return NULL;
  49. if (S->key == NULL) {
  50. S->key = xstrdup(k);
  51. S->d = d;
  52. return NULL;
  53. } else {
  54. stringmap S2;
  55. for (S2 = S;;) {
  56. int i = strcmp(k, S2->key);
  57. if (i == 0) {
  58. return &(S2->d);
  59. }
  60. else if (i < 0) {
  61. if (S2->l) S2 = S2->l;
  62. else {
  63. if (!(S2->l = stringmap_new())) return NULL;
  64. S2->l->key = xstrdup(k);
  65. S2->l->d = d;
  66. return NULL;
  67. }
  68. } else if (i > 0) {
  69. if (S2->g) S2 = S2->g;
  70. else {
  71. if (!(S2->g = stringmap_new())) return NULL;
  72. S2->g->key = xstrdup(k);
  73. S2->g->d = d;
  74. return NULL;
  75. }
  76. }
  77. }
  78. }
  79. }
  80. /* stringmap_find:
  81. * Find in d an item having key k in the stringmap S, returning the item found
  82. * on success NULL if no key was found. */
  83. stringmap stringmap_find(const stringmap S, const char *k) {
  84. stringmap S2;
  85. int i;
  86. if (!S || S->key == NULL) return 0;
  87. for (S2 = S;;) {
  88. i = strcmp(k, S2->key);
  89. if (i == 0) return S2;
  90. else if (i < 0) {
  91. if (S2->l) S2 = S2->l;
  92. else return NULL;
  93. } else if (i > 0) {
  94. if (S2->g) S2 = S2->g;
  95. else return NULL;
  96. }
  97. }
  98. }