save-flags.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /* -*- buffer-read-only: t -*- vi: set ro:
  2. *
  3. * DO NOT EDIT THIS FILE (save-flags.c)
  4. *
  5. * It has been AutoGen-ed
  6. * From the definitions /tmp/.ag-ufBbQe/save-flags.def
  7. * and the template file str2enum
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. 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. * 3. Neither the name ``Bruce Korb'' nor the name of any other
  18. * contributor may be used to endorse or promote products derived
  19. * from this software without specific prior written permission.
  20. *
  21. * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
  22. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
  25. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  28. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  30. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  31. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include "save-flags.h"
  34. #include <sys/types.h>
  35. #ifndef MISSING_INTTYPES_H
  36. # include <inttypes.h>
  37. #endif
  38. typedef enum {
  39. SVFL_BNM_DEFAULT = 0,
  40. SVFL_BNM_USAGE = 1,
  41. SVFL_BNM_UPDATE = 2,
  42. SVFL_COUNT_BNM
  43. } save_flags_enum_t;
  44. static save_flags_enum_t
  45. find_save_flags_bnm(char const * str, size_t len);
  46. #include <sys/types.h>
  47. #include <string.h>
  48. #ifndef NUL
  49. #define NUL '\0'
  50. #endif
  51. /* ANSI-C code produced by gperf version 3.1 */
  52. /* Command-line: gperf save-flags.gp */
  53. /* Computed positions: -k'' */
  54. # if 0 /* gperf build options: */
  55. // %struct-type
  56. // %language=ANSI-C
  57. // %includes
  58. // %global-table
  59. // %omit-struct-type
  60. // %readonly-tables
  61. // %compare-strncmp
  62. //
  63. // %define slot-name svfl_name
  64. // %define hash-function-name save_flags_hash
  65. // %define lookup-function-name find_save_flags_name
  66. // %define word-array-name save_flags_table
  67. // %define initializer-suffix ,SVFL_COUNT_BNM
  68. //
  69. # endif
  70. #include "save-flags.h"
  71. typedef struct {
  72. char const * svfl_name;
  73. save_flags_enum_t svfl_id;
  74. } save_flags_map_t;
  75. #include <string.h>
  76. /* maximum key range = 3, duplicates = 0 */
  77. static unsigned int
  78. save_flags_hash (register const char *str, register size_t len)
  79. {
  80. (void)str;
  81. (void)len;
  82. return len;
  83. }
  84. static const save_flags_map_t save_flags_table[] =
  85. {
  86. {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM},
  87. {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM},
  88. {"",SVFL_COUNT_BNM},
  89. {"usage", SVFL_BNM_USAGE},
  90. {"update", SVFL_BNM_UPDATE},
  91. {"default", SVFL_BNM_DEFAULT}
  92. };
  93. static inline const save_flags_map_t *
  94. find_save_flags_name (register const char *str, register size_t len)
  95. {
  96. if (len <= 7 && len >= 5)
  97. {
  98. register unsigned int key = (int)save_flags_hash (str, len);
  99. if (key <= 7)
  100. {
  101. register const char *s = save_flags_table[key].svfl_name;
  102. if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
  103. return &save_flags_table[key];
  104. }
  105. }
  106. return 0;
  107. }
  108. /**
  109. * Convert a command (keyword) to a save_flags_enum_t enumeration value.
  110. *
  111. * @param[in] str a string that should start with a known key word.
  112. * @param[in] len the provided length of the keyword at \a str.
  113. * @returns the enumeration value.
  114. * If not found, that value is SVFL_COUNT_BNM.
  115. */
  116. static save_flags_enum_t
  117. find_save_flags_bnm(char const * str, size_t len)
  118. {
  119. save_flags_map_t const * map;
  120. map = find_save_flags_name(str, (unsigned int)len);
  121. if (map != NULL)
  122. return map->svfl_id;
  123. /* Check for a partial match */
  124. {
  125. /*
  126. * Indexes of valid save_flags_table entries in sorted order:
  127. */
  128. static unsigned int const ix_map[] = {
  129. 7, 6, 5 };
  130. save_flags_enum_t res = SVFL_COUNT_BNM;
  131. static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1;
  132. int lo = 0;
  133. int hi = HI;
  134. int av;
  135. int cmp;
  136. for (;;) {
  137. av = (hi + lo) / 2;
  138. map = save_flags_table + ix_map[av];
  139. cmp = strncmp(map->svfl_name, str, len);
  140. if (cmp == 0) break;
  141. if (cmp > 0)
  142. hi = av - 1;
  143. else lo = av + 1;
  144. if (lo > hi)
  145. return SVFL_COUNT_BNM;
  146. }
  147. res = map->svfl_id;
  148. /*
  149. * If we have an exact match, accept it.
  150. */
  151. if (map->svfl_name[len] == NUL)
  152. return res;
  153. /*
  154. * Check for a duplicate partial match (a partial match
  155. * with a higher or lower index than "av".
  156. */
  157. if (av < HI) {
  158. map = save_flags_table + ix_map[av + 1];
  159. if (strncmp(map->svfl_name, str, len) == 0)
  160. return SVFL_COUNT_BNM;
  161. }
  162. if (av > 0) {
  163. map = save_flags_table + ix_map[av - 1];
  164. if (strncmp(map->svfl_name, str, len) == 0)
  165. return SVFL_COUNT_BNM;
  166. }
  167. return res;
  168. }
  169. }
  170. /**
  171. * Convert a string to a save_flags_mask_t mask.
  172. * Bit names prefixed with a hyphen have the bit removed from the mask.
  173. * If the string starts with a '-', '+' or '|' character, then
  174. * the old value is used as a base, otherwise the result mask
  175. * is initialized to zero. Separating bit names with '+' or '|'
  176. * characters is optional. By default, the bits are "or"-ed into the
  177. * result.
  178. *
  179. * @param[in] str string with a list of bit names
  180. * @param[in] old previous value, used if \a str starts with a '+' or '-'.
  181. *
  182. * @returns an unsigned integer with the bits set.
  183. */
  184. save_flags_mask_t
  185. save_flags_str2mask(char const * str, save_flags_mask_t old)
  186. {
  187. static char const white[] = ", \t\f";
  188. static char const name_chars[] =
  189. "adefglpstu"
  190. "ADEFGLPSTU";
  191. save_flags_mask_t res = 0;
  192. int have_data = 0;
  193. for (;;) {
  194. save_flags_enum_t val;
  195. unsigned int val_len;
  196. unsigned int invert = 0;
  197. str += strspn(str, white);
  198. switch (*str) {
  199. case NUL: return res;
  200. case '-': case '~':
  201. invert = 1;
  202. /* FALLTHROUGH */
  203. case '+': case '|':
  204. if (have_data == 0)
  205. res = old;
  206. str += 1 + strspn(str + 1, white);
  207. if (*str == NUL)
  208. return 0;
  209. }
  210. val_len = strspn(str, name_chars);
  211. if (val_len == 0)
  212. return 0;
  213. val = find_save_flags_bnm(str, val_len);
  214. if (val == SVFL_COUNT_BNM)
  215. return 0;
  216. if (invert)
  217. res &= ~((save_flags_mask_t)1 << val);
  218. else
  219. res |= (save_flags_mask_t)1 << val;
  220. have_data = 1;
  221. str += val_len;
  222. }
  223. }
  224. /* end of save-flags.c */