strset.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #ifndef CCAN_STRSET_H
  2. #define CCAN_STRSET_H
  3. #include "config.h"
  4. #include <ccan/typesafe_cb/typesafe_cb.h>
  5. #include <stdlib.h>
  6. #include <stdbool.h>
  7. /**
  8. * struct strset - representation of a string set
  9. *
  10. * It's exposed here to allow you to embed it and so we can inline the
  11. * trivial functions.
  12. */
  13. struct strset {
  14. union {
  15. struct node *n;
  16. const char *s;
  17. } u;
  18. };
  19. /**
  20. * strset_init - initialize a string set (empty)
  21. *
  22. * For completeness; if you've arranged for it to be NULL already you don't
  23. * need this.
  24. *
  25. * Example:
  26. * struct strset set;
  27. *
  28. * strset_init(&set);
  29. */
  30. static inline void strset_init(struct strset *set)
  31. {
  32. set->u.n = NULL;
  33. }
  34. /**
  35. * strset_empty - is this string set empty?
  36. * @set: the set.
  37. *
  38. * Example:
  39. * if (!strset_empty(&set))
  40. * abort();
  41. */
  42. static inline bool strset_empty(const struct strset *set)
  43. {
  44. return set->u.n == NULL;
  45. }
  46. /**
  47. * strset_test - is this a member of this string set?
  48. * @set: the set.
  49. * @member: the string to search for.
  50. *
  51. * Returns the member, or NULL if it isn't in the set (and sets errno
  52. * = ENOENT).
  53. *
  54. * Example:
  55. * if (strset_test(&set, "hello"))
  56. * printf("hello is in the set\n");
  57. */
  58. char *strset_test(const struct strset *set, const char *member);
  59. /**
  60. * strset_set - place a member in the string set.
  61. * @set: the set.
  62. * @member: the string to place in the set.
  63. *
  64. * This returns false if we run out of memory (errno = ENOMEM), or
  65. * (more normally) if that string already appears in the set (EEXIST).
  66. *
  67. * Note that the pointer is placed in the set, the string is not copied. If
  68. * you want a copy in the set, use strdup().
  69. *
  70. * Example:
  71. * if (!strset_set(&set, "goodbye"))
  72. * printf("goodbye was already in the set\n");
  73. */
  74. bool strset_set(struct strset *set, const char *member);
  75. /**
  76. * strset_clear - remove a member from the string set.
  77. * @set: the set.
  78. * @member: the string to remove from the set.
  79. *
  80. * This returns the string which was passed to strset_set(), or NULL if
  81. * the string was not in the map (in which case it sets errno = ENOENT).
  82. *
  83. * This means that if you allocated a string (eg. using strdup()), you can
  84. * free it here.
  85. *
  86. * Example:
  87. * if (!strset_clear(&set, "goodbye"))
  88. * printf("goodbye was not in the set?\n");
  89. */
  90. char *strset_clear(struct strset *set, const char *member);
  91. /**
  92. * strset_destroy - remove every member from the set.
  93. * @set: the set.
  94. *
  95. * The set will be empty after this.
  96. *
  97. * Example:
  98. * strset_destroy(&set);
  99. */
  100. void strset_destroy(struct strset *set);
  101. /**
  102. * strset_iterate - ordered iteration over a set
  103. * @set: the set.
  104. * @handle: the function to call.
  105. * @arg: the argument for the function (types should match).
  106. *
  107. * You should not alter the set within the @handle function! If it returns
  108. * true, the iteration will stop.
  109. *
  110. * Example:
  111. * static bool dump_some(const char *member, int *num)
  112. * {
  113. * // Only dump out num nodes.
  114. * if (*(num--) == 0)
  115. * return true;
  116. * printf("%s\n", member);
  117. * return false;
  118. * }
  119. *
  120. * static void dump_set(const struct strset *set)
  121. * {
  122. * int max = 100;
  123. * strset_iterate(set, dump_some, &max);
  124. * if (max < 0)
  125. * printf("... (truncated to 100 entries)\n");
  126. * }
  127. */
  128. #define strset_iterate(set, handle, arg) \
  129. strset_iterate_((set), typesafe_cb_preargs(bool, void *, \
  130. (handle), (arg), \
  131. const char *), \
  132. (arg))
  133. void strset_iterate_(const struct strset *set,
  134. bool (*handle)(const char *, void *), const void *data);
  135. /**
  136. * strset_prefix - return a subset matching a prefix
  137. * @set: the set.
  138. * @prefix: the prefix.
  139. *
  140. * This returns a pointer into @set, so don't alter @set while using
  141. * the return value. You can use strset_iterate(), strset_test() or
  142. * strset_empty() on the returned pointer.
  143. *
  144. * Example:
  145. * static void dump_prefix(const struct strset *set, const char *prefix)
  146. * {
  147. * int max = 100;
  148. * printf("Nodes with prefix %s:\n", prefix);
  149. * strset_iterate(strset_prefix(set, prefix), dump_some, &max);
  150. * if (max < 0)
  151. * printf("... (truncated to 100 entries)\n");
  152. * }
  153. */
  154. const struct strset *strset_prefix(const struct strset *set,
  155. const char *prefix);
  156. #endif /* CCAN_STRSET_H */