1
0

argtable3_private.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*******************************************************************************
  2. * argtable3_private: Declares private types, constants, and interfaces
  3. *
  4. * This file is part of the argtable3 library.
  5. *
  6. * Copyright (C) 2013-2019 Tom G. Huang
  7. * <tomghuang@gmail.com>
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * * Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * * Neither the name of STEWART HEITMANN nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL STEWART HEITMANN BE LIABLE FOR ANY DIRECT,
  25. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  28. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. ******************************************************************************/
  32. #ifndef ARG_UTILS_H
  33. #define ARG_UTILS_H
  34. #include <stdlib.h>
  35. #define ARG_ENABLE_TRACE 0
  36. #define ARG_ENABLE_LOG 1
  37. #ifdef __cplusplus
  38. extern "C" {
  39. #endif
  40. enum { ARG_ERR_MINCOUNT = 1, ARG_ERR_MAXCOUNT, ARG_ERR_BADINT, ARG_ERR_OVERFLOW, ARG_ERR_BADDOUBLE, ARG_ERR_BADDATE, ARG_ERR_REGNOMATCH };
  41. typedef void(arg_panicfn)(const char* fmt, ...);
  42. #if defined(_MSC_VER)
  43. #define ARG_TRACE(x) \
  44. __pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
  45. if (ARG_ENABLE_TRACE) \
  46. dbg_printf x; \
  47. } \
  48. while (0) \
  49. __pragma(warning(pop))
  50. #define ARG_LOG(x) \
  51. __pragma(warning(push)) __pragma(warning(disable : 4127)) do { \
  52. if (ARG_ENABLE_LOG) \
  53. dbg_printf x; \
  54. } \
  55. while (0) \
  56. __pragma(warning(pop))
  57. #else
  58. #define ARG_TRACE(x) \
  59. do { \
  60. if (ARG_ENABLE_TRACE) \
  61. dbg_printf x; \
  62. } while (0)
  63. #define ARG_LOG(x) \
  64. do { \
  65. if (ARG_ENABLE_LOG) \
  66. dbg_printf x; \
  67. } while (0)
  68. #endif
  69. extern void dbg_printf(const char* fmt, ...);
  70. extern void arg_set_panic(arg_panicfn* proc);
  71. extern void* xmalloc(size_t size);
  72. extern void* xcalloc(size_t count, size_t size);
  73. extern void* xrealloc(void* ptr, size_t size);
  74. extern void xfree(void* ptr);
  75. struct arg_hashtable_entry {
  76. void *k, *v;
  77. unsigned int h;
  78. struct arg_hashtable_entry* next;
  79. };
  80. typedef struct arg_hashtable {
  81. unsigned int tablelength;
  82. struct arg_hashtable_entry** table;
  83. unsigned int entrycount;
  84. unsigned int loadlimit;
  85. unsigned int primeindex;
  86. unsigned int (*hashfn)(const void* k);
  87. int (*eqfn)(const void* k1, const void* k2);
  88. } arg_hashtable_t;
  89. /**
  90. * @brief Create a hash table.
  91. *
  92. * @param minsize minimum initial size of hash table
  93. * @param hashfn function for hashing keys
  94. * @param eqfn function for determining key equality
  95. * @return newly created hash table or NULL on failure
  96. */
  97. arg_hashtable_t* arg_hashtable_create(unsigned int minsize, unsigned int (*hashfn)(const void*), int (*eqfn)(const void*, const void*));
  98. /**
  99. * @brief This function will cause the table to expand if the insertion would take
  100. * the ratio of entries to table size over the maximum load factor.
  101. *
  102. * This function does not check for repeated insertions with a duplicate key.
  103. * The value returned when using a duplicate key is undefined -- when
  104. * the hash table changes size, the order of retrieval of duplicate key
  105. * entries is reversed.
  106. * If in doubt, remove before insert.
  107. *
  108. * @param h the hash table to insert into
  109. * @param k the key - hash table claims ownership and will free on removal
  110. * @param v the value - does not claim ownership
  111. * @return non-zero for successful insertion
  112. */
  113. void arg_hashtable_insert(arg_hashtable_t* h, void* k, void* v);
  114. #define ARG_DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
  115. int fnname(arg_hashtable_t* h, keytype* k, valuetype* v) { return arg_hashtable_insert(h, k, v); }
  116. /**
  117. * @brief Search the specified key in the hash table.
  118. *
  119. * @param h the hash table to search
  120. * @param k the key to search for - does not claim ownership
  121. * @return the value associated with the key, or NULL if none found
  122. */
  123. void* arg_hashtable_search(arg_hashtable_t* h, const void* k);
  124. #define ARG_DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
  125. valuetype* fnname(arg_hashtable_t* h, keytype* k) { return (valuetype*)(arg_hashtable_search(h, k)); }
  126. /**
  127. * @brief Remove the specified key from the hash table.
  128. *
  129. * @param h the hash table to remove the item from
  130. * @param k the key to search for - does not claim ownership
  131. */
  132. void arg_hashtable_remove(arg_hashtable_t* h, const void* k);
  133. #define ARG_DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
  134. valuetype* fnname(arg_hashtable_t* h, keytype* k) { return (valuetype*)(arg_hashtable_remove(h, k)); }
  135. /**
  136. * @brief Return the number of keys in the hash table.
  137. *
  138. * @param h the hash table
  139. * @return the number of items stored in the hash table
  140. */
  141. unsigned int arg_hashtable_count(arg_hashtable_t* h);
  142. /**
  143. * @brief Change the value associated with the key.
  144. *
  145. * function to change the value associated with a key, where there already
  146. * exists a value bound to the key in the hash table.
  147. * Source due to Holger Schemel.
  148. *
  149. * @name hashtable_change
  150. * @param h the hash table
  151. * @param key
  152. * @param value
  153. */
  154. int arg_hashtable_change(arg_hashtable_t* h, void* k, void* v);
  155. /**
  156. * @brief Free the hash table and the memory allocated for each key-value pair.
  157. *
  158. * @param h the hash table
  159. * @param free_values whether to call 'free' on the remaining values
  160. */
  161. void arg_hashtable_destroy(arg_hashtable_t* h, int free_values);
  162. typedef struct arg_hashtable_itr {
  163. arg_hashtable_t* h;
  164. struct arg_hashtable_entry* e;
  165. struct arg_hashtable_entry* parent;
  166. unsigned int index;
  167. } arg_hashtable_itr_t;
  168. arg_hashtable_itr_t* arg_hashtable_itr_create(arg_hashtable_t* h);
  169. void arg_hashtable_itr_destroy(arg_hashtable_itr_t* itr);
  170. /**
  171. * @brief Return the value of the (key,value) pair at the current position.
  172. */
  173. extern void* arg_hashtable_itr_key(arg_hashtable_itr_t* i);
  174. /**
  175. * @brief Return the value of the (key,value) pair at the current position.
  176. */
  177. extern void* arg_hashtable_itr_value(arg_hashtable_itr_t* i);
  178. /**
  179. * @brief Advance the iterator to the next element. Returns zero if advanced to end of table.
  180. */
  181. int arg_hashtable_itr_advance(arg_hashtable_itr_t* itr);
  182. /**
  183. * @brief Remove current element and advance the iterator to the next element.
  184. */
  185. int arg_hashtable_itr_remove(arg_hashtable_itr_t* itr);
  186. /**
  187. * @brief Search and overwrite the supplied iterator, to point to the entry matching the supplied key.
  188. *
  189. * @return Zero if not found.
  190. */
  191. int arg_hashtable_itr_search(arg_hashtable_itr_t* itr, arg_hashtable_t* h, void* k);
  192. #define ARG_DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
  193. int fnname(arg_hashtable_itr_t* i, arg_hashtable_t* h, keytype* k) { return (arg_hashtable_iterator_search(i, h, k)); }
  194. #ifdef __cplusplus
  195. }
  196. #endif
  197. #endif