/*=export_func optionStackArg * private: * * what: put option args on a stack * arg: + tOptions* + opts + program options descriptor + * arg: + tOptDesc* + od + the descriptor for this arg + * * doc: * Keep an entry-ordered list of option arguments. =*/ void optionStackArg(tOptions * opts, tOptDesc * od) { char * pz; if (INQUERY_CALL(opts, od)) return; if ((od->fOptState & OPTST_RESET) != 0) { tArgList * arg_list = (void*)od->optCookie; int ix; if (arg_list == NULL) return; ix = arg_list->useCt; while (--ix >= 0) AGFREE(arg_list->apzArgs[ix]); AGFREE(arg_list); } else { if (od->optArg.argString == NULL) return; AGDUPSTR(pz, od->optArg.argString, "stack arg"); addArgListEntry(&(od->optCookie), (void*)pz); } }
/** * Associate a name with a boolean value * * @param[in,out] pp argument list to add to * @param[in] name the name of the "suboption" * @param[in] nm_len the length of the name * @param[in] val the boolean value for the suboption * @param[in] d_len the length of the value * * @returns the new value structure */ static tOptionValue * add_bool(void ** pp, char const * name, size_t nm_len, char const * val, size_t d_len) { size_t sz = nm_len + sizeof(tOptionValue) + 1; tOptionValue * new_val = AGALOC(sz, "bool val"); /* * Scan over whitespace is constrained by "d_len" */ while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { d_len--; val++; } if (d_len == 0) new_val->v.boolVal = 0; else if (IS_DEC_DIGIT_CHAR(*val)) new_val->v.boolVal = (unsigned)atoi(val); else new_val->v.boolVal = ! IS_FALSE_TYPE_CHAR(*val); 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; }
/*=export_func optionNestedVal * private: * * what: parse a hierarchical option argument * 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 * opts, tOptDesc * od) { if (opts < OPTPROC_EMIT_LIMIT) return; if (od->fOptState & OPTST_RESET) { tArgList * arg_list = od->optCookie; int ct; char const ** av; if (arg_list == NULL) return; ct = arg_list->useCt; av = arg_list->apzArgs; while (--ct >= 0) { void * p = VOIDP(*(av++)); optionUnloadNested((tOptionValue const *)p); } AGFREE(od->optCookie); } else { tOptionValue * opt_val = optionLoadNested( od->optArg.argString, od->pz_Name, strlen(od->pz_Name)); if (opt_val != NULL) addArgListEntry(&(od->optCookie), VOIDP(opt_val)); } }
/** * Associate a name with strtol() value, defaulting to zero. * * @param[in,out] pp argument list to add to * @param[in] name the name of the "suboption" * @param[in] nm_len the length of the name * @param[in] val the numeric value for the suboption * @param[in] d_len the length of the value * * @returns the new value structure */ static tOptionValue * add_number(void ** pp, char const * name, size_t nm_len, char const * val, size_t d_len) { size_t sz = nm_len + sizeof(tOptionValue) + 1; tOptionValue * new_val = AGALOC(sz, "int val"); /* * Scan over whitespace is constrained by "d_len" */ while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { d_len--; val++; } if (d_len == 0) new_val->v.longVal = 0; else 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, name, nm_len); new_val->pzName[ nm_len ] = NUL; addArgListEntry(pp, new_val); return new_val; }
/*=export_func optionStackArg * private: * * what: put option args on a stack * arg: + tOptions* + pOpts + program options descriptor + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + * * doc: * Keep an entry-ordered list of option arguments. =*/ void optionStackArg( tOptions* pOpts, tOptDesc* pOD ) { char * pz; if ((pOD->fOptState & OPTST_RESET) != 0) { tArgList* pAL = (void*)pOD->optCookie; int ix; if (pAL == NULL) return; ix = pAL->useCt; while (--ix >= 0) AGFREE(pAL->apzArgs[ix]); AGFREE(pAL); } else { if (pOD->optArg.argString == NULL) return; AGDUPSTR(pz, pOD->optArg.argString, "stack arg"); addArgListEntry( &(pOD->optCookie), (void*)pz ); } }
/*=export_func optionNestedVal * private: * * what: parse a hierarchical option argument * arg: + tOptions* + pOpts + program options descriptor + * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + * * doc: * Nested value was found on the command line =*/ void optionNestedVal(tOptions* pOpts, tOptDesc* pOD) { if (pOpts < OPTPROC_EMIT_LIMIT) return; if (pOD->fOptState & OPTST_RESET) { tArgList* pAL = pOD->optCookie; int ct; tCC ** av; if (pAL == NULL) return; ct = pAL->useCt; av = pAL->apzArgs; while (--ct >= 0) { void * p = (void *)(intptr_t)*(av++); optionUnloadNested((tOptionValue const *)p); } AGFREE(pOD->optCookie); } else { tOptionValue* pOV = optionLoadNested( pOD->optArg.argString, pOD->pz_Name, strlen(pOD->pz_Name)); if (pOV != NULL) addArgListEntry( &(pOD->optCookie), (void*)pOV ); } }
/* addNestedValue * * Associate a name with either a string or no value. */ static tOptionValue* addNestedValue( void** pp, char const* pzName, size_t nameLen, char* pzValue, size_t dataLen ) { tOptionValue* pNV; if (dataLen == 0) { size_t sz = nameLen + sizeof(*pNV) + 1; pNV = AGALOC( sz, "empty nested value pair" ); if (pNV == 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; } else { pNV = optionLoadNested( pzValue, pzName, nameLen ); } if (pNV != NULL) addArgListEntry( pp, pNV ); return pNV; }
/* addNumberValue * * Associate a name with either a string or no value. */ static tOptionValue* addNumberValue( void** pp, char const* pzName, size_t nameLen, char const* pzValue, size_t dataLen ) { tOptionValue* pNV; size_t sz = nameLen + sizeof(*pNV) + 1; pNV = AGALOC( sz, "option name/bool value pair" ); if (pNV == NULL) return NULL; while (IS_WHITESPACE_CHAR(*pzValue) && (dataLen > 0)) { dataLen--; pzValue++; } if (dataLen == 0) pNV->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; }
/* addBoolValue * * Associate a name with either a string or no value. */ static tOptionValue* addBoolValue( void** pp, char const* pzName, size_t nameLen, char const* pzValue, size_t dataLen ) { tOptionValue* pNV; size_t sz = nameLen + sizeof(*pNV) + 1; pNV = AGALOC( sz, "option name/bool value pair" ); if (pNV == NULL) return NULL; while (IS_WHITESPACE_CHAR(*pzValue) && (dataLen > 0)) { dataLen--; pzValue++; } if (dataLen == 0) pNV->v.boolVal = 0; else if (IS_DEC_DIGIT_CHAR(*pzValue)) pNV->v.boolVal = atoi(pzValue); else pNV->v.boolVal = ! IS_FALSE_TYPE_CHAR(*pzValue); pNV->valType = OPARG_TYPE_BOOLEAN; pNV->pzName = (char*)(pNV + 1); memcpy( pNV->pzName, pzName, nameLen ); pNV->pzName[ nameLen ] = NUL; addArgListEntry( pp, pNV ); return pNV; }
/* addStringValue * * Associate a name with either a string or no value. */ static tOptionValue* addStringValue( void** pp, char const* pzName, size_t nameLen, char const* pzValue, size_t dataLen ) { tOptionValue* pNV; size_t sz = nameLen + dataLen + sizeof(*pNV); pNV = AGALOC( sz, "option name/str value pair" ); if (pNV == NULL) return NULL; if (pzValue == NULL) { pNV->valType = OPARG_TYPE_NONE; pNV->pzName = pNV->v.strVal; } else { pNV->valType = OPARG_TYPE_STRING; if (dataLen > 0) { char const * pzSrc = pzValue; char * pzDst = pNV->v.strVal; int ct = dataLen; do { int ch = *(pzSrc++) & 0xFF; if (ch == NUL) goto data_copy_done; if (ch == '&') ch = get_special_char(&pzSrc, &ct); *(pzDst++) = ch; } while (--ct > 0); data_copy_done: *pzDst = NUL; } else { pNV->v.strVal[0] = NUL; } pNV->pzName = pNV->v.strVal + dataLen + 1; } memcpy( pNV->pzName, pzName, nameLen ); pNV->pzName[ nameLen ] = NUL; addArgListEntry( pp, pNV ); return pNV; }
/** * Associate a name with either a string or no value. * * @param[in,out] pp argument list to add to * @param[in] name the name of the "suboption" * @param[in] nm_len the length of the name * @param[in] val the string value for the suboption * @param[in] d_len the length of the value * * @returns the new value structure */ static tOptionValue * add_string(void ** pp, char const * name, size_t nm_len, char const * val, size_t d_len) { tOptionValue * pNV; size_t sz = nm_len + d_len + sizeof(*pNV); pNV = AGALOC(sz, "option name/str value pair"); if (val == NULL) { pNV->valType = OPARG_TYPE_NONE; pNV->pzName = pNV->v.strVal; } else { pNV->valType = OPARG_TYPE_STRING; if (d_len > 0) { char const * src = val; char * pzDst = pNV->v.strVal; int ct = (int)d_len; do { int ch = *(src++) & 0xFF; if (ch == NUL) goto data_copy_done; if (ch == '&') ch = get_special_char(&src, &ct); *(pzDst++) = (char)ch; } while (--ct > 0); data_copy_done: *pzDst = NUL; } else { pNV->v.strVal[0] = NUL; } pNV->pzName = pNV->v.strVal + d_len + 1; } memcpy(pNV->pzName, name, nm_len); pNV->pzName[ nm_len ] = NUL; addArgListEntry(pp, pNV); return pNV; }
/** * Associate a name with a nested/hierarchical value. * * @param[in,out] pp argument list to add to * @param[in] name the name of the "suboption" * @param[in] nm_len the length of the name * @param[in] val the nested values for the suboption * @param[in] d_len the length of the value * * @returns the new value structure */ static tOptionValue * add_nested(void ** pp, char const * name, size_t nm_len, char * val, size_t d_len) { tOptionValue * new_val; if (d_len == 0) { size_t sz = nm_len + sizeof(*new_val) + 1; new_val = AGALOC(sz, "empty nest"); new_val->v.nestVal = NULL; new_val->valType = OPARG_TYPE_HIERARCHY; new_val->pzName = (char *)(new_val + 1); memcpy(new_val->pzName, name, nm_len); new_val->pzName[ nm_len ] = NUL; } else { new_val = optionLoadNested(val, name, nm_len); } if (new_val != NULL) addArgListEntry(pp, new_val); return new_val; }