diff options
Diffstat (limited to 'src/libopts/nested.c')
-rw-r--r-- | src/libopts/nested.c | 624 |
1 files changed, 344 insertions, 280 deletions
diff --git a/src/libopts/nested.c b/src/libopts/nested.c index ed23fd2036..bf55f6f18a 100644 --- a/src/libopts/nested.c +++ b/src/libopts/nested.c @@ -2,13 +2,17 @@ /** * \file nested.c * - * Time-stamp: "2012-03-04 13:30:07 bkorb" + * Handle options with arguments that contain nested values. * + * @addtogroup autoopts + * @{ + */ +/* * Automated Options Nested Values module. * * This file is part of AutoOpts, a companion to AutoGen. * AutoOpts is free software. - * AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved + * AutoOpts is Copyright (C) 1992-2013 by Bruce Korb - all rights reserved * * AutoOpts is available under any one of two licenses. The license * in use must be one of these two and the choice is under the control @@ -20,11 +24,11 @@ * The Modified Berkeley Software Distribution License * See the file "COPYING.mbsd" * - * These files have the following md5sums: + * These files have the following sha256 sums: * - * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 - * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 - * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd */ typedef struct { @@ -47,35 +51,44 @@ static xml_xlate_t const xml_xlate[] = { /* = = = START-STATIC-FORWARD = = = */ static void -remove_continuation(char* pzSrc); +remove_continuation(char * src); static char const* scan_q_str(char const* pzTxt); static tOptionValue * -add_string(void ** pp, char const * pzName, size_t nameLen, +add_string(void ** pp, char const * name, size_t nm_len, char const* pzValue, size_t dataLen); static tOptionValue * -add_bool(void ** pp, char const * pzName, size_t nameLen, - char const* pzValue, size_t dataLen); +add_bool(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); static tOptionValue* -add_number(void** pp, char const* pzName, size_t nameLen, - char const* pzValue, size_t dataLen); +add_number(void** pp, char const* pzName, size_t nm_len, + char const* val, size_t d_len); static tOptionValue* -add_nested(void** pp, char const* pzName, size_t nameLen, - char* pzValue, size_t dataLen); +add_nested(void** pp, char const* pzName, size_t nm_len, + char* val, size_t d_len); static char const * scan_name(char const* pzName, tOptionValue* pRes); -static char const* -scan_xml(char const* pzName, tOptionValue* pRes); +static char const * +unnamed_xml(char const * txt); + +static char const * +scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val); + +static char const * +find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len); + +static char const * +scan_xml(char const * xml_name, tOptionValue * res_val); static void -sort_list(tArgList* pAL); +sort_list(tArgList * arg_list); /* = = = END-STATIC-FORWARD = = = */ /** @@ -83,13 +96,13 @@ sort_list(tArgList* pAL); * characters, but trim out the backslash: */ static void -remove_continuation(char* pzSrc) +remove_continuation(char * src) { char* pzD; do { - while (*pzSrc == NL) pzSrc++; - pzD = strchr(pzSrc, NL); + while (*src == NL) src++; + pzD = strchr(src, NL); if (pzD == NULL) return; @@ -98,20 +111,20 @@ remove_continuation(char* pzSrc) * points to a newline character. It now becomes the source and * pzD goes to the previous character. */ - pzSrc = pzD--; + src = pzD--; if (*pzD != '\\') pzD++; - } while (pzD == pzSrc); + } while (pzD == src); /* * Start shifting text. */ for (;;) { - char ch = ((*pzD++) = *(pzSrc++)); + char ch = ((*pzD++) = *(src++)); switch (ch) { case NUL: return; case '\\': - if (*pzSrc == NL) + if (*src == NL) --pzD; /* rewrite on next iteration */ } } @@ -158,11 +171,11 @@ scan_q_str(char const* pzTxt) * Associate a name with either a string or no value. */ static tOptionValue * -add_string(void ** pp, char const * pzName, size_t nameLen, +add_string(void ** pp, char const * name, size_t nm_len, char const* pzValue, size_t dataLen) { tOptionValue* pNV; - size_t sz = nameLen + dataLen + sizeof(*pNV); + size_t sz = nm_len + dataLen + sizeof(*pNV); pNV = AGALOC(sz, "option name/str value pair"); if (pNV == NULL) @@ -175,14 +188,14 @@ add_string(void ** pp, char const * pzName, size_t nameLen, } else { pNV->valType = OPARG_TYPE_STRING; if (dataLen > 0) { - char const * pzSrc = pzValue; + char const * src = pzValue; char * pzDst = pNV->v.strVal; - int ct = dataLen; + int ct = (int)dataLen; do { - int ch = *(pzSrc++) & 0xFF; + int ch = *(src++) & 0xFF; if (ch == NUL) goto data_copy_done; if (ch == '&') - ch = get_special_char(&pzSrc, &ct); + ch = get_special_char(&src, &ct); *(pzDst++) = (char)ch; } while (--ct > 0); data_copy_done: @@ -195,8 +208,8 @@ add_string(void ** pp, char const * pzName, size_t nameLen, pNV->pzName = pNV->v.strVal + dataLen + 1; } - memcpy(pNV->pzName, pzName, nameLen); - pNV->pzName[ nameLen ] = NUL; + memcpy(pNV->pzName, name, nm_len); + pNV->pzName[ nm_len ] = NUL; addArgListEntry(pp, pNV); return pNV; } @@ -205,95 +218,95 @@ add_string(void ** pp, char const * pzName, size_t nameLen, * Associate a name with either a string or no value. */ static tOptionValue * -add_bool(void ** pp, char const * pzName, size_t nameLen, - char const* pzValue, size_t dataLen) +add_bool(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) { - tOptionValue * pNV; + tOptionValue * new_val; { - size_t sz = nameLen + sizeof(tOptionValue) + 1; - pNV = AGALOC(sz, "name/bool value"); + size_t sz = nm_len + sizeof(tOptionValue) + 1; + new_val = AGALOC(sz, "name/bool value"); } { - char * p = SPN_WHITESPACE_CHARS(pzValue); - dataLen -= p - pzValue; - pzValue = p; + char * p = SPN_WHITESPACE_CHARS(val); + d_len -= (unsigned long)(p - val); + val = p; } - if (dataLen == 0) - pNV->v.boolVal = 0; + if (d_len == 0) + new_val->v.boolVal = 0; - else if (IS_DEC_DIGIT_CHAR(*pzValue)) - pNV->v.boolVal = atoi(pzValue); + else if (IS_DEC_DIGIT_CHAR(*val)) + new_val->v.boolVal = (unsigned)atoi(val); - else pNV->v.boolVal = ! IS_FALSE_TYPE_CHAR(*pzValue); + else new_val->v.boolVal = ! IS_FALSE_TYPE_CHAR(*val); - pNV->valType = OPARG_TYPE_BOOLEAN; - pNV->pzName = (char*)(pNV + 1); - memcpy(pNV->pzName, pzName, nameLen); - pNV->pzName[ nameLen ] = NUL; - addArgListEntry(pp, pNV); - return pNV; + new_val->valType = OPARG_TYPE_BOOLEAN; + new_val->pzName = (char*)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + addArgListEntry(pp, new_val); + return new_val; } /** * Associate a name with either a string or no value. */ static tOptionValue* -add_number(void** pp, char const* pzName, size_t nameLen, - char const* pzValue, size_t dataLen) +add_number(void** pp, char const* pzName, size_t nm_len, + char const* val, size_t d_len) { - tOptionValue* pNV; - size_t sz = nameLen + sizeof(*pNV) + 1; + tOptionValue* new_val; + size_t sz = nm_len + sizeof(*new_val) + 1; - pNV = AGALOC(sz, "option name/bool value pair"); - if (pNV == NULL) + new_val = AGALOC(sz, "bool val"); + if (new_val == NULL) return NULL; - while (IS_WHITESPACE_CHAR(*pzValue) && (dataLen > 0)) { - dataLen--; pzValue++; + while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { + d_len--; val++; } - if (dataLen == 0) - pNV->v.longVal = 0; + if (d_len == 0) + new_val->v.longVal = 0; else - pNV->v.longVal = strtol(pzValue, 0, 0); - - pNV->valType = OPARG_TYPE_NUMERIC; - pNV->pzName = (char*)(pNV + 1); - memcpy(pNV->pzName, pzName, nameLen); - pNV->pzName[ nameLen ] = NUL; - addArgListEntry(pp, pNV); - return pNV; + new_val->v.longVal = strtol(val, 0, 0); + + new_val->valType = OPARG_TYPE_NUMERIC; + new_val->pzName = (char*)(new_val + 1); + memcpy(new_val->pzName, pzName, nm_len); + new_val->pzName[ nm_len ] = NUL; + addArgListEntry(pp, new_val); + return new_val; } /** * Associate a name with either a string or no value. */ static tOptionValue* -add_nested(void** pp, char const* pzName, size_t nameLen, - char* pzValue, size_t dataLen) +add_nested(void** pp, char const* pzName, size_t nm_len, + char* val, size_t d_len) { - tOptionValue* pNV; + tOptionValue* new_val; - if (dataLen == 0) { - size_t sz = nameLen + sizeof(*pNV) + 1; - pNV = AGALOC(sz, "empty nested value pair"); - if (pNV == NULL) + if (d_len == 0) { + size_t sz = nm_len + sizeof(*new_val) + 1; + new_val = AGALOC(sz, "empty nest"); + if (new_val == NULL) return NULL; - pNV->v.nestVal = NULL; - pNV->valType = OPARG_TYPE_HIERARCHY; - pNV->pzName = (char*)(pNV + 1); - memcpy(pNV->pzName, pzName, nameLen); - pNV->pzName[ nameLen ] = NUL; + new_val->v.nestVal = NULL; + new_val->valType = OPARG_TYPE_HIERARCHY; + new_val->pzName = (char*)(new_val + 1); + memcpy(new_val->pzName, pzName, nm_len); + new_val->pzName[ nm_len ] = NUL; } else { - pNV = optionLoadNested(pzValue, pzName, nameLen); + new_val = optionLoadNested(val, pzName, nm_len); } - if (pNV != NULL) - addArgListEntry(pp, pNV); + if (new_val != NULL) + addArgListEntry(pp, new_val); - return pNV; + return new_val; } /** @@ -303,11 +316,11 @@ add_nested(void** pp, char const* pzName, size_t nameLen, static char const * scan_name(char const* pzName, tOptionValue* pRes) { - tOptionValue* pNV; + tOptionValue* new_val; char const * pzScan = pzName+1; /* we know first char is a name char */ char const * pzVal; - size_t nameLen = 1; - size_t dataLen = 0; + size_t nm_len = 1; + size_t d_len = 0; /* * Scan over characters that name a value. These names may not end @@ -316,7 +329,7 @@ scan_name(char const* pzName, tOptionValue* pRes) pzScan = SPN_VALUE_NAME_CHARS(pzName + 1); if (pzScan[-1] == ':') pzScan--; - nameLen = pzScan - pzName; + nm_len = (size_t)(pzScan - pzName); pzScan = SPN_HORIZ_WHITE_CHARS(pzScan); @@ -336,18 +349,18 @@ scan_name(char const* pzName, tOptionValue* pRes) /* FALLTHROUGH */ case NUL: - add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0); + add_string(&(pRes->v.nestVal), pzName, nm_len, NULL, (size_t)0); break; case '"': case '\'': pzVal = pzScan; pzScan = scan_q_str(pzScan); - dataLen = pzScan - pzVal; - pNV = add_string(&(pRes->v.nestVal), pzName, nameLen, pzVal, - dataLen); - if ((pNV != NULL) && (option_load_mode == OPTION_LOAD_COOKED)) - ao_string_cook(pNV->v.strVal, NULL); + d_len = (size_t)(pzScan - pzVal); + new_val = add_string(&(pRes->v.nestVal), pzName, nm_len, pzVal, + d_len); + if ((new_val != NULL) && (option_load_mode == OPTION_LOAD_COOKED)) + ao_string_cook(new_val->v.strVal, NULL); break; default: @@ -362,7 +375,7 @@ scan_name(char const* pzName, tOptionValue* pRes) switch (ch) { case NUL: pzScan--; - dataLen = pzScan - pzVal; + d_len = (size_t)(pzScan - pzVal); goto string_done; /* FALLTHROUGH */ @@ -374,12 +387,12 @@ scan_name(char const* pzName, tOptionValue* pRes) /* FALLTHROUGH */ case ',': - dataLen = (pzScan - pzVal) - 1; + d_len = (size_t)(pzScan - pzVal) - 1; string_done: - pNV = add_string(&(pRes->v.nestVal), pzName, nameLen, - pzVal, dataLen); - if (pNV != NULL) - remove_continuation(pNV->v.strVal); + new_val = add_string(&(pRes->v.nestVal), pzName, nm_len, + pzVal, d_len); + if (new_val != NULL) + remove_continuation(new_val->v.strVal); goto leave_scan_name; } } @@ -390,139 +403,193 @@ scan_name(char const* pzName, tOptionValue* pRes) } /** - * We've found a '<' character. We ignore this if it is a comment or a - * directive. If it is something else, then whatever it is we are looking - * at is bogus. Returning NULL stops processing. + * Some xml element that does not start with a name. + * The next character must be either '!' (introducing a comment), + * or '?' (introducing an XML meta-marker of some sort). + * We ignore these and indicate an error (NULL result) otherwise. + * + * @param[in] txt the text within an xml bracket + * @returns the address of the character after the closing marker, or NULL. */ -static char const* -scan_xml(char const* pzName, tOptionValue* pRes) +static char const * +unnamed_xml(char const * txt) { - size_t nameLen; - size_t valLen; - char const* pzScan = ++pzName; - char const* pzVal; - tOptionValue valu; - tOptionValue* pNewVal; - tOptionLoadMode save_mode = option_load_mode; - - if (! IS_VAR_FIRST_CHAR(*pzName)) { - switch (*pzName) { - default: - pzName = NULL; - break; + switch (*txt) { + default: + txt = NULL; + break; - case '!': - pzName = strstr(pzName, "-->"); - if (pzName != NULL) - pzName += 3; - break; + case '!': + txt = strstr(txt, "-->"); + if (txt != NULL) + txt += 3; + break; - case '?': - pzName = strchr(pzName, '>'); - if (pzName != NULL) - pzName++; - break; - } - return pzName; + case '?': + txt = strchr(txt, '>'); + if (txt != NULL) + txt++; + break; } + return txt; +} - pzScan = SPN_VALUE_NAME_CHARS(pzName+1); - nameLen = pzScan - pzName; - if (nameLen > 64) +/** + * Scan off the xml element name, and the rest of the header, too. + * Set the value type to NONE if it ends with "/>". + * + * @param[in] name the first name character (alphabetic) + * @param[out] nm_len the length of the name + * @param[out] val set valType field to STRING or NONE. + * + * @returns the scan resumption point, or NULL on error + */ +static char const * +scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val) +{ + char const * scan = SPN_VALUE_NAME_CHARS(name + 1); + *nm_len = (size_t)(scan - name); + if (*nm_len > 64) return NULL; - valu.valType = OPARG_TYPE_STRING; + val->valType = OPARG_TYPE_STRING; - switch (*pzScan) { - case ' ': - case '\t': - pzScan = parse_attrs( - NULL, (char*)pzScan, &option_load_mode, &valu ); - if (*pzScan == '>') { - pzScan++; - break; - } + if (IS_WHITESPACE_CHAR(*scan)) { + /* + * There are attributes following the name. Parse 'em. + */ + scan = SPN_WHITESPACE_CHARS(scan); + scan = parse_attrs(NULL, scan, &option_load_mode, val); + if (scan == NULL) + return NULL; /* oops */ + } - if (*pzScan != '/') { - option_load_mode = save_mode; - return NULL; - } - /* FALLTHROUGH */ + if (! IS_END_XML_TOKEN_CHAR(*scan)) + return NULL; /* oops */ - case '/': - if (*++pzScan != '>') { - option_load_mode = save_mode; + if (*scan == '/') { + /* + * Single element XML entries get inserted as an empty string. + */ + if (*++scan != '>') return NULL; - } - add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0); - option_load_mode = save_mode; - return pzScan+1; - - default: - option_load_mode = save_mode; - return NULL; - - case '>': - pzScan++; - break; + val->valType = OPARG_TYPE_NONE; } + return scan+1; +} + +/** + * We've found a closing '>' without a preceding '/', thus we must search + * the text for '<name/>' where "name" is the name of the XML element. + * + * @param[in] name the start of the name in the element header + * @param[in] nm_len the length of that name + * @param[out] len the length of the value (string between header and + * the trailer/tail. + * @returns the character after the trailer, or NULL if not found. + */ +static char const * +find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len) +{ + char z[72] = "</"; + char * dst = z + 2; - pzVal = pzScan; + do { + *(dst++) = *(src++); + } while (--nm_len > 0); /* nm_len is known to be 64 or less */ + *(dst++) = '>'; + *dst = NUL; { - char z[68]; - char* pzD = z; - int ct = nameLen; - char const* pzS = pzName; - - *(pzD++) = '<'; - *(pzD++) = '/'; - - do { - *(pzD++) = *(pzS++); - } while (--ct > 0); - *(pzD++) = '>'; - *pzD = NUL; - - pzScan = strstr(pzScan, z); - if (pzScan == NULL) { - option_load_mode = save_mode; - return NULL; + char const * res = strstr(val, z); + + if (res != NULL) { + char const * end = (option_load_mode != OPTION_LOAD_KEEP) + ? SPN_WHITESPACE_BACK(val, res) + : res; + *len = (size_t)(end - val); /* includes trailing white space */ + res = SPN_WHITESPACE_CHARS(res + (dst - z)); } - valLen = (pzScan - pzVal); - pzScan += nameLen + 3; - pzScan = SPN_WHITESPACE_CHARS(pzScan); + return res; } +} + +/** + * We've found a '<' character. We ignore this if it is a comment or a + * directive. If it is something else, then whatever it is we are looking + * at is bogus. Returning NULL stops processing. + * + * @param[in] xml_name the name of an xml bracket (usually) + * @param[in,out] res_val the option data derived from the XML element + * + * @returns the place to resume scanning input + */ +static char const * +scan_xml(char const * xml_name, tOptionValue * res_val) +{ + size_t nm_len, v_len; + char const * scan; + char const * val_str; + tOptionValue valu; + tOptionLoadMode save_mode = option_load_mode; + + if (! IS_VAR_FIRST_CHAR(*++xml_name)) + return unnamed_xml(xml_name); + + /* + * "scan_xml_name()" may change "option_load_mode". + */ + val_str = scan_xml_name(xml_name, &nm_len, &valu); + if (val_str == NULL) + goto bail_scan_xml; + + if (valu.valType == OPARG_TYPE_NONE) + scan = val_str; + else { + if (option_load_mode != OPTION_LOAD_KEEP) + val_str = SPN_WHITESPACE_CHARS(val_str); + scan = find_end_xml(xml_name, nm_len, val_str, &v_len); + if (scan == NULL) + goto bail_scan_xml; + } + + /* + * "scan" now points to where the scan is to resume after returning. + * It either points after "/>" at the end of the XML element header, + * or it points after the "</name>" tail based on the name in the header. + */ switch (valu.valType) { case OPARG_TYPE_NONE: - add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0); + add_string(&(res_val->v.nestVal), xml_name, nm_len, NULL, 0); break; case OPARG_TYPE_STRING: - pNewVal = add_string( - &(pRes->v.nestVal), pzName, nameLen, pzVal, valLen); + { + tOptionValue * new_val = add_string( + &(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + + if (option_load_mode != OPTION_LOAD_KEEP) + munge_str(new_val->v.strVal, option_load_mode); - if (option_load_mode == OPTION_LOAD_KEEP) - break; - mungeString(pNewVal->v.strVal, option_load_mode); break; + } case OPARG_TYPE_BOOLEAN: - add_bool(&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen); + add_bool(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); break; case OPARG_TYPE_NUMERIC: - add_number(&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen); + add_number(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); break; case OPARG_TYPE_HIERARCHY: { - char* pz = AGALOC(valLen+1, "hierarchical scan"); + char * pz = AGALOC(v_len+1, "h scan"); if (pz == NULL) break; - memcpy(pz, pzVal, valLen); - pz[valLen] = NUL; - add_nested(&(pRes->v.nestVal), pzName, nameLen, pz, valLen); + memcpy(pz, val_str, v_len); + pz[v_len] = NUL; + add_nested(&(res_val->v.nestVal), xml_name, nm_len, pz, v_len); AGFREE(pz); break; } @@ -534,7 +601,11 @@ scan_xml(char const* pzName, tOptionValue* pRes) } option_load_mode = save_mode; - return pzScan; + return scan; + +bail_scan_xml: + option_load_mode = save_mode; + return NULL; } @@ -545,19 +616,19 @@ scan_xml(char const* pzName, tOptionValue* pRes) * knowing what they are doing. */ LOCAL void -unload_arg_list(tArgList* pAL) +unload_arg_list(tArgList * arg_list) { - int ct = pAL->useCt; - tCC** ppNV = pAL->apzArgs; + int ct = arg_list->useCt; + char const ** pnew_val = arg_list->apzArgs; while (ct-- > 0) { - tOptionValue* pNV = (tOptionValue*)(void*)*(ppNV++); - if (pNV->valType == OPARG_TYPE_HIERARCHY) - unload_arg_list(pNV->v.nestVal); - AGFREE(pNV); + tOptionValue* new_val = (tOptionValue*)(void*)*(pnew_val++); + if (new_val->valType == OPARG_TYPE_HIERARCHY) + unload_arg_list(new_val->v.nestVal); + AGFREE(new_val); } - AGFREE((void*)pAL); + AGFREE((void*)arg_list); } /*=export_func optionUnloadNested @@ -571,17 +642,17 @@ unload_arg_list(tArgList* pAL) * @pxref{libopts-configFileLoad}). =*/ void -optionUnloadNested(tOptionValue const * pOV) +optionUnloadNested(tOptionValue const * opt_val) { - if (pOV == NULL) return; - if (pOV->valType != OPARG_TYPE_HIERARCHY) { + if (opt_val == NULL) return; + if (opt_val->valType != OPARG_TYPE_HIERARCHY) { errno = EINVAL; return; } - unload_arg_list(pOV->v.nestVal); + unload_arg_list(opt_val->v.nestVal); - AGFREE((void*)pOV); + AGFREE((void*)opt_val); } /** @@ -590,27 +661,27 @@ optionUnloadNested(tOptionValue const * pOV) * Typically, we also hope the input is sorted. */ static void -sort_list(tArgList* pAL) +sort_list(tArgList * arg_list) { int ix; - int lm = pAL->useCt; + int lm = arg_list->useCt; /* * This loop iterates "useCt" - 1 times. */ for (ix = 0; ++ix < lm;) { int iy = ix-1; - tOptionValue* pNewNV = (tOptionValue*)(void*)(pAL->apzArgs[ix]); - tOptionValue* pOldNV = (tOptionValue*)(void*)(pAL->apzArgs[iy]); + tOptionValue * new_v = C(tOptionValue *, arg_list->apzArgs[ix]); + tOptionValue * old_v = C(tOptionValue *, arg_list->apzArgs[iy]); /* * For as long as the new entry precedes the "old" entry, * move the old pointer. Stop before trying to extract the * "-1" entry. */ - while (strcmp(pOldNV->pzName, pNewNV->pzName) > 0) { - pAL->apzArgs[iy+1] = (void*)pOldNV; - pOldNV = (tOptionValue*)(void*)(pAL->apzArgs[--iy]); + while (strcmp(old_v->pzName, new_v->pzName) > 0) { + arg_list->apzArgs[iy+1] = (void*)old_v; + old_v = (tOptionValue*)(void*)(arg_list->apzArgs[--iy]); if (iy < 0) break; } @@ -619,7 +690,7 @@ sort_list(tArgList* pAL) * Always store the pointer. Sometimes it is redundant, * but the redundancy is cheaper than a test and branch sequence. */ - pAL->apzArgs[iy+1] = (void*)pNewNV; + arg_list->apzArgs[iy+1] = (void*)new_v; } } @@ -627,9 +698,9 @@ sort_list(tArgList* pAL) * private: * * what: parse a hierarchical option argument - * arg: + char const* + pzTxt + the text to scan + - * arg: + char const* + pzName + the name for the text + - * arg: + size_t + nameLen + the length of "name" + + * arg: + char const * + pzTxt + the text to scan + + * arg: + char const * + pzName + the name for the text + + * arg: + size_t + nm_len + the length of "name" + * * ret_type: tOptionValue* * ret_desc: An allocated, compound value structure @@ -649,65 +720,57 @@ sort_list(tArgList* pAL) * @code{ENOMSG} no configuration values were found * @end itemize =*/ -LOCAL tOptionValue* -optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen) +LOCAL tOptionValue * +optionLoadNested(char const * text, char const * name, size_t nm_len) { - tOptionValue* pRes; + tOptionValue* res_val; /* * Make sure we have some data and we have space to put what we find. */ - if (pzTxt == NULL) { + if (text == NULL) { errno = EINVAL; return NULL; } - pzTxt = SPN_WHITESPACE_CHARS(pzTxt); - if (*pzTxt == NUL) { + text = SPN_WHITESPACE_CHARS(text); + if (*text == NUL) { errno = ENOMSG; return NULL; } - pRes = AGALOC(sizeof(*pRes) + nameLen + 1, "nested args"); - if (pRes == NULL) { - errno = ENOMEM; - return NULL; - } - pRes->valType = OPARG_TYPE_HIERARCHY; - pRes->pzName = (char*)(pRes + 1); - memcpy(pRes->pzName, pzName, nameLen); - pRes->pzName[nameLen] = NUL; + res_val = AGALOC(sizeof(*res_val) + nm_len + 1, "nest args"); + res_val->valType = OPARG_TYPE_HIERARCHY; + res_val->pzName = (char*)(res_val + 1); + memcpy(res_val->pzName, name, nm_len); + res_val->pzName[nm_len] = NUL; { - tArgList * pAL = AGALOC(sizeof(*pAL), "nested arg list"); - if (pAL == NULL) { - AGFREE(pRes); - return NULL; - } + tArgList * arg_list = AGALOC(sizeof(*arg_list), "nest arg l"); - pRes->v.nestVal = pAL; - pAL->useCt = 0; - pAL->allocCt = MIN_ARG_ALLOC_CT; + res_val->v.nestVal = arg_list; + arg_list->useCt = 0; + arg_list->allocCt = MIN_ARG_ALLOC_CT; } /* * Scan until we hit a NUL. */ do { - pzTxt = SPN_WHITESPACE_CHARS(pzTxt); - if (IS_VAR_FIRST_CHAR(*pzTxt)) - pzTxt = scan_name(pzTxt, pRes); + text = SPN_WHITESPACE_CHARS(text); + if (IS_VAR_FIRST_CHAR(*text)) + text = scan_name(text, res_val); - else switch (*pzTxt) { + else switch (*text) { case NUL: goto scan_done; - case '<': pzTxt = scan_xml(pzTxt, pRes); - if (pzTxt == NULL) goto woops; - if (*pzTxt == ',') pzTxt++; break; - case '#': pzTxt = strchr(pzTxt, NL); break; + case '<': text = scan_xml(text, res_val); + if (text == NULL) goto woops; + if (*text == ',') text++; break; + case '#': text = strchr(text, NL); break; default: goto woops; } - } while (pzTxt != NULL); scan_done:; + } while (text != NULL); scan_done:; { - tArgList * al = pRes->v.nestVal; + tArgList * al = res_val->v.nestVal; if (al->useCt == 0) { errno = ENOMSG; goto woops; @@ -716,11 +779,11 @@ optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen) sort_list(al); } - return pRes; + return res_val; woops: - AGFREE(pRes->v.nestVal); - AGFREE(pRes); + AGFREE(res_val->v.nestVal); + AGFREE(res_val); return NULL; } @@ -728,45 +791,45 @@ optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen) * private: * * what: parse a hierarchical option argument - * arg: + tOptions* + pOpts + program options descriptor + - * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + + * arg: + tOptions* + opts + program options descriptor + + * arg: + tOptDesc* + od + the descriptor for this arg + * * doc: * Nested value was found on the command line =*/ void -optionNestedVal(tOptions* pOpts, tOptDesc* pOD) +optionNestedVal(tOptions * opts, tOptDesc * od) { - if (pOpts < OPTPROC_EMIT_LIMIT) + if (opts < OPTPROC_EMIT_LIMIT) return; - if (pOD->fOptState & OPTST_RESET) { - tArgList* pAL = pOD->optCookie; - int ct; - tCC ** av; + if (od->fOptState & OPTST_RESET) { + tArgList * arg_list = od->optCookie; + int ct; + char const ** av; - if (pAL == NULL) + if (arg_list == NULL) return; - ct = pAL->useCt; - av = pAL->apzArgs; + ct = arg_list->useCt; + av = arg_list->apzArgs; while (--ct >= 0) { void * p = (void *)*(av++); optionUnloadNested((tOptionValue const *)p); } - AGFREE(pOD->optCookie); + AGFREE(od->optCookie); } else { - tOptionValue* pOV = optionLoadNested( - pOD->optArg.argString, pOD->pz_Name, strlen(pOD->pz_Name)); + tOptionValue * opt_val = optionLoadNested( + od->optArg.argString, od->pz_Name, strlen(od->pz_Name)); - if (pOV != NULL) - addArgListEntry(&(pOD->optCookie), (void*)pOV); + if (opt_val != NULL) + addArgListEntry(&(od->optCookie), (void*)opt_val); } } -/* +/** * get_special_char */ LOCAL int @@ -789,7 +852,7 @@ get_special_char(char const ** ppz, int * ct) retch = (int)strtoul(pz, (char **)&pz, base); if (*pz != ';') return '&'; - base = ++pz - *ppz; + base = (int)(++pz - *ppz); if (base > *ct) return '&'; @@ -804,7 +867,7 @@ get_special_char(char const ** ppz, int * ct) for (;;) { if ( (*ct >= xlatp->xml_len) - && (strncmp(pz, xlatp->xml_txt, xlatp->xml_len) == 0)) { + && (strncmp(pz, xlatp->xml_txt, (size_t)xlatp->xml_len) == 0)) { *ppz += xlatp->xml_len; *ct -= xlatp->xml_len; return xlatp->xml_ch; @@ -818,7 +881,7 @@ get_special_char(char const ** ppz, int * ct) return '&'; } -/* +/** * emit_special_char */ LOCAL void @@ -840,7 +903,8 @@ emit_special_char(FILE * fp, int ch) fprintf(fp, XML_HEX_BYTE_FMT, (ch & 0xFF)); } -/* +/** @} + * * Local Variables: * mode: C * c-file-style: "stroustrup" |