/* -*- buffer-read-only: t -*- vi: set ro: * * DO NOT EDIT THIS FILE (directive.c) * * It has been AutoGen-ed * From the definitions directive.def * and the template file str2enum * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name ``Bruce Korb'' nor the name of any other * contributor may be used to endorse or promote products derived * from this software without specific prior written permission. * * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "directive.h" #include #include /** \file directive.c * Code for string to enumeration values and back again. * @addtogroup autogen * @{ */ /* ANSI-C code produced by gperf version 3.0.4 */ /* Command-line: gperf directive.gp */ /* Computed positions: -k'2,4' */ # if 0 /* gperf build options: */ // %struct-type // %language=ANSI-C // %includes // %global-table // %omit-struct-type // %readonly-tables // %compare-strncmp // // %define slot-name dir_name // %define hash-function-name directive_hash // %define lookup-function-name find_directive_name // %define word-array-name directive_table // %define initializer-suffix ,DIR_COUNT // # endif #include "directive.h" typedef struct { char const * dir_name; directive_enum_t dir_id; } directive_map_t; #include /* maximum key range = 34, duplicates = 0 */ static unsigned int directive_hash (register const char *str, register unsigned int len) { static const unsigned char asso_values[] = { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 10, 37, 37, 20, 0, 5, 5, 20, 15, 37, 37, 5, 5, 0, 5, 5, 37, 5, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 }; register int hval = len; switch (hval) { default: hval += asso_values[(unsigned char)str[3]]; /*FALLTHROUGH*/ case 3: case 2: hval += asso_values[(unsigned char)str[1]]; break; } return hval; } static const directive_map_t directive_table[] = { {"",DIR_COUNT}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"let", DIR_LET}, {"",DIR_COUNT}, {"undef", DIR_UNDEF}, {"assert", DIR_ASSERT}, {"if", DIR_IF}, {"endshell", DIR_ENDSHELL}, {"else", DIR_ELSE}, {"ifdef", DIR_IFDEF}, {"endmac", DIR_ENDMAC}, {"include", DIR_INCLUDE}, {"",DIR_COUNT}, {"elif", DIR_ELIF}, {"error", DIR_ERROR}, {"pragma", DIR_PRAGMA}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"line", DIR_LINE}, {"endif", DIR_ENDIF}, {"define", DIR_DEFINE}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"ident", DIR_IDENT}, {"option", DIR_OPTION}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"shell", DIR_SHELL}, {"ifndef", DIR_IFNDEF}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"",DIR_COUNT}, {"macdef", DIR_MACDEF} }; static inline const directive_map_t * find_directive_name (register const char *str, register unsigned int len) { if (len <= 8 && len >= 2) { register int key = (int)directive_hash (str, len); if (key <= 36 && key >= 0) { register const char *s = directive_table[key].dir_name; if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') return &directive_table[key]; } } return 0; } /** * Convert a command (keyword) to a directive_enum_t enumeration value. * The length of the command is computed by calling \a strspn() * on the input argument. * * @param[in] str a string that should start with a known key word. * @returns the enumeration value. * If not found, that value is DIR_INVALID. */ directive_enum_t find_directive(char const * str) { directive_map_t const * map; static char const accept[] = "acdefghilmnoprstu"; unsigned int clen = strspn(str, accept); if (isalnum((unsigned char)str[clen])) return DIR_INVALID; map = find_directive_name(str, (unsigned int)clen); return (map == NULL) ? DIR_INVALID : map->dir_id; } /** * Convert an directive_enum_t value into a string. * * @param[in] id the enumeration value * @returns the associated string, or "* UNDEFINED *" if \a id * is out of range. */ char const * directive_name(directive_enum_t id) { static char const undef[] = "* UNDEFINED *"; static char const * const nm_table[] = { [DIR_ASSERT ] = "assert", [DIR_DEFINE ] = "define", [DIR_ELIF ] = "elif", [DIR_ELSE ] = "else", [DIR_ENDIF ] = "endif", [DIR_ENDMAC ] = "endmac", [DIR_ENDSHELL] = "endshell", [DIR_ERROR ] = "error", [DIR_IDENT ] = "ident", [DIR_IF ] = "if", [DIR_IFDEF ] = "ifdef", [DIR_IFNDEF ] = "ifndef", [DIR_INCLUDE ] = "include", [DIR_LET ] = "let", [DIR_LINE ] = "line", [DIR_MACDEF ] = "macdef", [DIR_OPTION ] = "option", [DIR_PRAGMA ] = "pragma", [DIR_SHELL ] = "shell", [DIR_UNDEF ] = "undef" }; char const * res = undef; if (id < DIR_COUNT) { res = nm_table[id]; if (res == NULL) res = undef; } return res; } /** * Dispatch a directive function, based on the keyword. * * @param[in] str a string that should start with a known key word. * @returns char *, returned by the dispatched function. */ char * doDir_directive_disp(char const * str, char * scan_next) { static doDir_hdl_t * const dispatch[22] = { [DIR_ASSERT ] = doDir_assert, [DIR_DEFINE ] = doDir_define, [DIR_ELIF ] = doDir_elif, [DIR_ELSE ] = doDir_else, [DIR_ENDIF ] = doDir_endif, [DIR_ENDMAC ] = doDir_endmac, [DIR_ENDSHELL] = doDir_endshell, [DIR_ERROR ] = doDir_error, [DIR_IDENT ] = doDir_ident, [DIR_IF ] = doDir_if, [DIR_IFDEF ] = doDir_ifdef, [DIR_IFNDEF ] = doDir_ifndef, [DIR_INCLUDE ] = doDir_include, [DIR_LET ] = doDir_let, [DIR_LINE ] = doDir_line, [DIR_MACDEF ] = doDir_macdef, [DIR_OPTION ] = doDir_option, [DIR_PRAGMA ] = doDir_pragma, [DIR_SHELL ] = doDir_shell, [DIR_UNDEF ] = doDir_undef, [DIR_INVALID ] = doDir_invalid }; static unsigned int keywd_len[] = { [DIR_ASSERT ] = 6, [DIR_DEFINE ] = 6, [DIR_ELIF ] = 4, [DIR_ELSE ] = 4, [DIR_ENDIF ] = 5, [DIR_ENDMAC ] = 6, [DIR_ENDSHELL] = 8, [DIR_ERROR ] = 5, [DIR_IDENT ] = 5, [DIR_IF ] = 2, [DIR_IFDEF ] = 5, [DIR_IFNDEF ] = 6, [DIR_INCLUDE ] = 7, [DIR_LET ] = 3, [DIR_LINE ] = 4, [DIR_MACDEF ] = 6, [DIR_OPTION ] = 6, [DIR_PRAGMA ] = 6, [DIR_SHELL ] = 5, [DIR_UNDEF ] = 5 }; directive_enum_t id = find_directive(str); unsigned int klen = keywd_len[id]; doDir_hdl_t * disp = dispatch[id]; if (disp == NULL) disp = dispatch[DIR_INVALID]; return disp(id, str + klen, scan_next); } /** @} */ /* end of directive.c */