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 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 * 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 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 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