/** * "txt" points to the character after "members=" * What should follow is a name of a "set membership". * A collection of bit flags. * * @param opts unused * @param[in] txt keyword to skip over * @param type unused value type * @returns pointer after skipped text */ static char const * parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ) { (void)opts; (void)typ; return skip_unkn(txt); }
/** * parse the type. The keyword "type" was found, now figure out * the type that follows the type. * * @param[in] txt points to the '=' character after the "type" keyword. * @param[out] typ where to store the type found * @returns the next byte after the type name */ static char const * parse_value(char const * txt, tOptionValue * typ) { size_t len = 0; if (*(txt++) != '=') goto woops; len = (size_t)(SPN_OPTION_NAME_CHARS(txt) - txt); if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(txt[len]))) { woops: typ->valType = OPARG_TYPE_NONE; return skip_unkn(txt + len); } /* * The enumeration used in this switch is derived from this switch * statement itself. The "find_option_value_type_cmd" function * will return VTP_CMD_INTEGER for the "txt" string value * "integer", etc. */ switch (find_option_value_type_cmd(txt, len)) { default: case VTP_INVALID_CMD: goto woops; case VTP_CMD_STRING: typ->valType = OPARG_TYPE_STRING; break; case VTP_CMD_INTEGER: typ->valType = OPARG_TYPE_NUMERIC; break; case VTP_CMD_BOOL: case VTP_CMD_BOOLEAN: typ->valType = OPARG_TYPE_BOOLEAN; break; case VTP_CMD_KEYWORD: typ->valType = OPARG_TYPE_ENUMERATION; break; case VTP_CMD_SET: case VTP_CMD_SET_MEMBERSHIP: typ->valType = OPARG_TYPE_MEMBERSHIP; break; case VTP_CMD_NESTED: case VTP_CMD_HIERARCHY: typ->valType = OPARG_TYPE_HIERARCHY; } return txt + len; }
/** * "pzText" points to the character after "type=" */ static char * parse_value(char * pzText, tOptionValue * pType) { size_t len = 0; if (*(pzText++) != '=') goto woops; while (IS_OPTION_NAME_CHAR(pzText[len])) len++; pzText += len; if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(*pzText))) { woops: pType->valType = OPARG_TYPE_NONE; return skip_unkn(pzText); } switch (find_value_type_id(pzText - len, len)) { default: case VTP_KWD_INVALID: goto woops; case VTP_KWD_STRING: pType->valType = OPARG_TYPE_STRING; break; case VTP_KWD_INTEGER: pType->valType = OPARG_TYPE_NUMERIC; break; case VTP_KWD_BOOL: case VTP_KWD_BOOLEAN: pType->valType = OPARG_TYPE_BOOLEAN; break; case VTP_KWD_KEYWORD: pType->valType = OPARG_TYPE_ENUMERATION; break; case VTP_KWD_SET: case VTP_KWD_SET_MEMBERSHIP: pType->valType = OPARG_TYPE_MEMBERSHIP; break; case VTP_KWD_NESTED: case VTP_KWD_HIERARCHY: pType->valType = OPARG_TYPE_HIERARCHY; } return pzText; }
/** * Parse the various attributes of an XML-styled config file entry * * @returns NULL on failure, otherwise the scan point */ LOCAL char const * parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, tOptionValue * pType) { size_t len = 0; for (;;) { len = (size_t)(SPN_LOWER_CASE_CHARS(txt) - txt); /* * The enumeration used in this switch is derived from this switch * statement itself. The "find_option_xat_attribute_cmd" function * will return XAT_CMD_MEMBERS for the "txt" string value * "members", etc. */ switch (find_option_xat_attribute_cmd(txt, len)) { case XAT_CMD_TYPE: txt = parse_value(txt+len, pType); break; case XAT_CMD_WORDS: txt = parse_keyword(opts, txt+len, pType); break; case XAT_CMD_MEMBERS: txt = parse_set_mem(opts, txt+len, pType); break; case XAT_CMD_COOKED: txt += len; if (! IS_END_XML_TOKEN_CHAR(*txt)) goto invalid_kwd; *pMode = OPTION_LOAD_COOKED; break; case XAT_CMD_UNCOOKED: txt += len; if (! IS_END_XML_TOKEN_CHAR(*txt)) goto invalid_kwd; *pMode = OPTION_LOAD_UNCOOKED; break; case XAT_CMD_KEEP: txt += len; if (! IS_END_XML_TOKEN_CHAR(*txt)) goto invalid_kwd; *pMode = OPTION_LOAD_KEEP; break; default: case XAT_INVALID_CMD: invalid_kwd: pType->valType = OPARG_TYPE_NONE; return skip_unkn(txt); } if (txt == NULL) return NULL; txt = SPN_WHITESPACE_CHARS(txt); switch (*txt) { case '/': pType->valType = OPARG_TYPE_NONE; /* FALLTHROUGH */ case '>': return txt; } if (! IS_LOWER_CASE_CHAR(*txt)) return NULL; } }
/** * "pzText" points to the character after "members=" * What should follow is a name of a "set membership". * A collection of bit flags. */ static char* parse_set_mem(tOptions * pOpts, char * pzText, tOptionValue * pType) { return skip_unkn(pzText); }
/** * Parse the various attributes of an XML-styled config file entry */ LOCAL char* parseAttributes( tOptions* pOpts, char* pzText, tOptionLoadMode* pMode, tOptionValue* pType ) { size_t len; do { if (! IS_WHITESPACE_CHAR(*pzText)) switch (*pzText) { case '/': pType->valType = OPARG_TYPE_NONE; case '>': return pzText; default: case NUL: return NULL; } while (IS_WHITESPACE_CHAR(*++pzText)) ; len = 0; while (IS_LOWER_CASE_CHAR(pzText[len])) len++; switch (find_xat_attribute_id(pzText, len)) { case XAT_KWD_TYPE: pzText = parse_value(pzText+len, pType); break; case XAT_KWD_WORDS: pzText = parse_keyword(pOpts, pzText+len, pType); break; case XAT_KWD_MEMBERS: pzText = parse_set_mem(pOpts, pzText+len, pType); break; case XAT_KWD_COOKED: pzText += len; if (! IS_END_XML_TOKEN_CHAR(*pzText)) goto invalid_kwd; *pMode = OPTION_LOAD_COOKED; break; case XAT_KWD_UNCOOKED: pzText += len; if (! IS_END_XML_TOKEN_CHAR(*pzText)) goto invalid_kwd; *pMode = OPTION_LOAD_UNCOOKED; break; case XAT_KWD_KEEP: pzText += len; if (! IS_END_XML_TOKEN_CHAR(*pzText)) goto invalid_kwd; *pMode = OPTION_LOAD_KEEP; break; default: case XAT_KWD_INVALID: invalid_kwd: pType->valType = OPARG_TYPE_NONE; return skip_unkn(pzText); } } while (pzText != NULL); return pzText; }