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
39 typedef enum {
40 SVFL_BNM_DEFAULT = 0,
41 SVFL_BNM_USAGE = 1,
42 SVFL_BNM_UPDATE = 2,
43 SVFL_COUNT_BNM
44 } save_flags_enum_t;
45
46 static save_flags_enum_t
47 find_save_flags_bnm(char const * str, size_t len);
48
49
50 #include <sys/types.h>
51 #include <string.h>
52 #ifndef NUL
53 #define NUL '\0'
54 #endif
55
56 /* ANSI-C code produced by gperf version 3.1 */
57 /* Command-line: gperf save-flags.gp */
58 /* Computed positions: -k'' */
59
60
61 # if 0 /* gperf build options: */
62 // %struct-type
63 // %language=ANSI-C
64 // %includes
65 // %global-table
66 // %omit-struct-type
67 // %readonly-tables
68 // %compare-strncmp
69 //
70 // %define slot-name svfl_name
71 // %define hash-function-name save_flags_hash
72 // %define lookup-function-name find_save_flags_name
73 // %define word-array-name save_flags_table
74 // %define initializer-suffix ,SVFL_COUNT_BNM
75 //
76 # endif
77
78 #include "save-flags.h"
79 typedef struct {
80 char const * svfl_name;
81 save_flags_enum_t svfl_id;
82 } save_flags_map_t;
83 #include <string.h>
84
85 /* maximum key range = 3, duplicates = 0 */
86
87 static unsigned int
save_flags_hash(register const char * str,register size_t len)88 save_flags_hash (register const char *str, register size_t len)
89 {
90 (void)str;
91 (void)len;
92 return len;
93 }
94
95 static const save_flags_map_t save_flags_table[] =
96 {
97 {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM},
98 {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM},
99 {"",SVFL_COUNT_BNM},
100 {"usage", SVFL_BNM_USAGE},
101 {"update", SVFL_BNM_UPDATE},
102 {"default", SVFL_BNM_DEFAULT}
103 };
104
105 static inline const save_flags_map_t *
find_save_flags_name(register const char * str,register size_t len)106 find_save_flags_name (register const char *str, register size_t len)
107 {
108 if (len <= 7 && len >= 5)
109 {
110 register unsigned int key = (int)save_flags_hash (str, len);
111
112 if (key <= 7)
113 {
114 register const char *s = save_flags_table[key].svfl_name;
115
116 if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
117 return &save_flags_table[key];
118 }
119 }
120 return 0;
121 }
122
123 /**
124 * Convert a command (keyword) to a save_flags_enum_t enumeration value.
125 *
126 * @param[in] str a string that should start with a known key word.
127 * @param[in] len the provided length of the keyword at \a str.
128 * @returns the enumeration value.
129 * If not found, that value is SVFL_COUNT_BNM.
130 */
131 static save_flags_enum_t
find_save_flags_bnm(char const * str,size_t len)132 find_save_flags_bnm(char const * str, size_t len)
133 {
134 save_flags_map_t const * map;
135
136 map = find_save_flags_name(str, (unsigned int)len);
137 if (map != NULL)
138 return map->svfl_id;
139 /* Check for a partial match */
140 {
141 /*
142 * Indexes of valid save_flags_table entries in sorted order:
143 */
144 static unsigned int const ix_map[] = {
145 7, 6, 5 };
146 save_flags_enum_t res = SVFL_COUNT_BNM;
147 static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1;
148 int lo = 0;
149 int hi = HI;
150 int av;
151 int cmp;
152
153 for (;;) {
154 av = (hi + lo) / 2;
155 map = save_flags_table + ix_map[av];
156 cmp = strncmp(map->svfl_name, str, len);
157 if (cmp == 0) break;
158 if (cmp > 0)
159 hi = av - 1;
160 else lo = av + 1;
161 if (lo > hi)
162 return SVFL_COUNT_BNM;
163 }
164 res = map->svfl_id;
165 /*
166 * If we have an exact match, accept it.
167 */
168 if (map->svfl_name[len] == NUL)
169 return res;
170 /*
171 * Check for a duplicate partial match (a partial match
172 * with a higher or lower index than "av".
173 */
174 if (av < HI) {
175 map = save_flags_table + ix_map[av + 1];
176 if (strncmp(map->svfl_name, str, len) == 0)
177 return SVFL_COUNT_BNM;
178 }
179 if (av > 0) {
180 map = save_flags_table + ix_map[av - 1];
181 if (strncmp(map->svfl_name, str, len) == 0)
182 return SVFL_COUNT_BNM;
183 }
184 return res;
185 }
186 }
187
188 /**
189 * Convert a string to a save_flags_mask_t mask.
190 * Bit names prefixed with a hyphen have the bit removed from the mask.
191 * If the string starts with a '-', '+' or '|' character, then
192 * the old value is used as a base, otherwise the result mask
193 * is initialized to zero. Separating bit names with '+' or '|'
194 * characters is optional. By default, the bits are "or"-ed into the
195 * result.
196 *
197 * @param[in] str string with a list of bit names
198 * @param[in] old previous value, used if \a str starts with a '+' or '-'.
199 *
200 * @returns an unsigned integer with the bits set.
201 */
202 save_flags_mask_t
save_flags_str2mask(char const * str,save_flags_mask_t old)203 save_flags_str2mask(char const * str, save_flags_mask_t old)
204 {
205 static char const white[] = ", \t\f";
206 static char const name_chars[] =
207 "adefglpstu"
208 "ADEFGLPSTU";
209
210 save_flags_mask_t res = 0;
211 int have_data = 0;
212
213 for (;;) {
214 save_flags_enum_t val;
215 unsigned int val_len;
216 unsigned int invert = 0;
217
218 str += strspn(str, white);
219 switch (*str) {
220 case NUL: return res;
221 case '-': case '~':
222 invert = 1;
223 /* FALLTHROUGH */
224
225 case '+': case '|':
226 if (have_data == 0)
227 res = old;
228
229 str += 1 + strspn(str + 1, white);
230 if (*str == NUL)
231 return 0;
232 }
233
234 val_len = strspn(str, name_chars);
235 if (val_len == 0)
236 return 0;
237 val = find_save_flags_bnm(str, val_len);
238 if (val == SVFL_COUNT_BNM)
239 return 0;
240 if (invert)
241 res &= ~((save_flags_mask_t)1 << val);
242 else
243 res |= (save_flags_mask_t)1 << val;
244 have_data = 1;
245 str += val_len;
246 }
247 }
248 /* end of save-flags.c */
249