/* **************************************************************************** * * paIsOption - is the string 'string' an option? */ bool paIsOption(PaiArgument* paList, char* string) { int len; PaiArgument* aP; LM_ENTRY(); paIterateInit(); while ((aP = paIterateNext(paList)) != NULL) { if ((aP->option == NULL) || (aP->option[0] == 0)) { continue; } len = MAX(strlen(aP->option), strlen(string)); if (strncmp(aP->option, string, len) == 0) { LM_EXIT(); return true; } } LM_EXIT(); return false; }
/* **************************************************************************** * * paValueFrom - */ PaFrom paValueFrom(char* oName) { PaiArgument* aP; paIterateInit(); while ((aP = paIterateNext(paiList)) != NULL) { char envVarName[64]; if (aP->option == NULL) { continue; } paEnvName(aP, envVarName, sizeof(envVarName)); if (aP->option && (strcmp(oName, aP->option) == 0)) { return aP->from; } else if (aP->envName && (strcmp(oName, envVarName) == 0)) { return aP->from; } } return PafError; }
/* **************************************************************************** * * paBuiltinRemove */ int paBuiltinRemove(char* name) { PaiArgument* aP; /* 1. lookup aP->option or aP->variable */ /* 2. if found - mark the aP as PaRemoved */ /* 3. Then paConfig needs the actions to do it */ paIterateInit(); while ((aP = paIterateNext(NULL)) != NULL) { char envVarName[128]; paEnvName(aP, envVarName, sizeof(envVarName)); if (((aP->option) && (strcmp(name, aP->option) == 0)) || ((aP->envName) && (strcmp(name, envVarName) == 0))) { aP->removed = true; break; } } if (aP == NULL) { char w[512]; snprintf(w, sizeof(w), "cannot remove builtin '%s' - not found", name); PA_WARNING(PasBuiltinRemove, w); return 1; } return 0; }
/* **************************************************************************** * * paBuiltinLookup - */ PaiArgument* paBuiltinLookup(char* option) { PaiArgument* aP; paIterateInit(); while ((aP = paIterateNext(NULL)) != NULL) { if (strcmp(aP->option, option) == 0) return aP; } return NULL; }
/* **************************************************************************** * * paFrom - from where did the value come? */ char* paFrom(PaiArgument* paList, const char* name) { PaiArgument* aP; paIterateInit(); while ((aP = paIterateNext(paList)) != NULL) { char envVarName[128]; paEnvName(aP, envVarName, sizeof(envVarName)); if ((aP->option) && strcmp(aP->option, name) == 0) { break; } if ((aP->envName) && strcmp(envVarName, name) == 0) { break; } } if (aP->type == PaLastArg) { return (char*) "unrecognized option"; } switch (aP->from) { case PafError: return (char*) "error"; case PafUnchanged: return (char*) "not altered"; case PafDefault: return (char*) "default value"; case PafEnvVar: return (char*) "environment variable"; case PafRcFile: return (char*) "RC file"; case PafArgument: return (char*) "command line argument"; } return (char*) "origin unknown"; }
/* **************************************************************************** * * paManUsage - */ static void paManUsage(void) { PaiArgument* aP; paIterateInit(); while ((aP = paIterateNext(paiList)) != NULL) { if (aP->sort == PaHid) { continue; } if ((aP->what & PawOption) == 0) { printf("Skipping '%s' (what == %d)\n", aP->option, aP->what); continue; } printf(" %-20s %s\n", aP->option, aP->description); } }
/* **************************************************************************** * * paOptionsParse - */ int paOptionsParse(PaiArgument* paList, char* argV[], int argC) { PaiArgument* aP; char* valueP; int argNo = 0; int param = 1; bool extendedUsage = false; char w[512]; LM_ENTRY(); w[0] = 0; PA_M(("incoming arg list of %d args", argC)); while (++argNo < argC) { char e[80]; char o[80]; int eee; int* eP; eP = &eee; *eP = PaNotOk; PA_M(("Looking up '%s'", argV[argNo])); if ((aP = argFind(paList, argV[argNo], STRICT, NULL)) != NULL) { valueP = argV[++argNo]; if (aP->type == PaBoolean) --argNo; } else if ((aP = argFind(paList, argV[argNo], UNSTRICT, NULL)) != NULL) valueP = &argV[argNo][strlen(aP->option)]; else if ((aP = argFind(paList, (char*) "", UNSTRICT, ¶m)) != NULL) valueP = argV[argNo]; else { snprintf(w, sizeof(w), "%s '%s' not recognized", optOrPar(argV[argNo]), argV[argNo]); PA_W(("Warning: '%s'", w)); PA_WARNING(PasNoSuchOption, w); continue; } LM_T(LmtPaApVals, ("found option '%s'", aP->name)); if (aP->varP == (void*) &paUsageVar) { memset(paResultString, 0, sizeof(paResultString)); if (extendedUsage == false) { paUsage(); return -2; } } else if (aP->varP == (void*) &paVersion) { paVersionPrint(); exit(0); } else if (aP->varP == (void*) &paLogDir) { if (valueP != NULL) { snprintf(paLogDir, sizeof(paLogDir), "%s", (char*) valueP); printf("log directory: '%s'\n", paLogDir); } } else if (aP->varP == (void*) &paEUsageVar) extendedUsage = true; else if (aP->varP == (void*) &paHelpVar) { memset(paResultString, 0, sizeof(paResultString)); paHelp(); return -2; } if (aP->used > 0) { if ((aP->type != PaSList) && (aP->type != PaIList) && (aP->what != PawParameter)) { snprintf(w, sizeof(w), "multiple use of %s", aP->name); PA_WARNING(PasMultipleOptionUse, w); continue; } } aP->from = PafArgument; if (aP->type == PaBoolean) { if (strlen(argV[argNo]) != strlen(aP->option)) { char tmp[128]; snprintf(w, sizeof(w), "boolean option '%s' doesn't take parameters", paFullName(aP, e, sizeof(e))); snprintf(tmp, sizeof(tmp), "%c%s", argV[argNo][0], &argV[argNo][2]); LM_W(("Changing arg %d from '%s' to '%s'", argNo, argV[argNo], tmp)); snprintf(argV[argNo], strlen(argV[argNo]), "%s", tmp); --argNo; } *((bool*) aP->varP) = (((bool) ((int) aP->def)) == true)? false : true; aP->used++; continue; } if ((argNo >= argC) || (paIsOption(paList, valueP) == true)) { REQUIRE(aP); break; } paFullName(aP, o, sizeof(o)); switch (aP->type) { case PaInt: case PaIntU: *((int*) aP->varP) = (int) (int64_t) paGetVal(valueP, eP); if (*eP != PaOk) { return -1; } LM_T(LmtPaApVals, ("got value %d for %s", *((int*) aP->varP), aP->name)); break; case PaInt64: case PaIntU64: *((int64_t*) aP->varP) = (int64_t) paGetVal(valueP, eP); if (*eP != PaOk) { return -1; } LM_T(LmtPaApVals, ("got value %ul for %s", *((int64_t*) aP->varP), aP->name)); break; case PaChar: case PaCharU: *((char*) aP->varP) = (char) (int64_t) paGetVal(valueP, eP); if (*eP != PaOk) { return -1; } LM_T(LmtPaApVals, ("got value %d for %s", *((char*) aP->varP), aP->name)); break; case PaShort: case PaShortU: *((int16_t*) aP->varP) = (int16_t) (int64_t) paGetVal(valueP, eP); if (*eP != PaOk) { return -1; } LM_T(LmtPaApVals, ("got value %d for %s", *((int16_t*) aP->varP), aP->name)); break; case PaFloat: *((float*) aP->varP) = baStof(valueP); *eP = PaOk; LM_T(LmtPaApVals, ("got value %f for %s", *((float*) aP->varP), aP->name)); break; case PaDouble: *((double*) aP->varP) = baStof(valueP); *eP = PaOk; LM_T(LmtPaApVals, ("got value %f for %s", *((double*) aP->varP), aP->name)); break; case PaString: strcpy((char*) aP->varP, valueP); LM_T(LmtPaApVals, ("got value '%s' for %s", (char*) aP->varP, aP->name)); *eP = PaOk; break; case PaIList: LM_T(LmtPaIList, ("setting list '%s' to var %s", valueP, aP->name)); iListFix((int*) aP->varP, valueP, eP); break; case PaSList: LM_T(LmtPaSList, ("setting list '%s' to var %s", valueP, aP->name)); sListFix((char**) aP->varP, valueP, eP); break; case PaBoolean: case PaLastArg: LM_T(LmtPaApVals, ("PaList, PaBoolean, PaLastArg ...")); *eP = PaOk; break; default: LM_W(("bad type for option '%s'", aP->name)); } if (*eP != PaOk) { REQUIRE(aP); } aP->used++; LM_V(("%s used %d times", aP->name, aP->used)); } /* checking that all required arguments are set */ paIterateInit(); while ((aP = paIterateNext(paList)) != NULL) { if ((aP->sort == PaReq) && (aP->used == 0)) { snprintf(w, sizeof(w), "%s required", aP->name); PA_WARNING(PasRequiredOption, w); } } if (extendedUsage == true) { paExtendedUsage(); return -2; } LM_EXIT(); return 0; }
/* **************************************************************************** * * argFind - search the slot in the argument list corresponding to 'string' */ static PaiArgument* argFind ( PaiArgument* paList, char* string, int strict, int* parNoP ) { PaiArgument* aP; PaiArgument* foundP = NULL; int foundNameLen = 0; LM_ENTRY(); paIterateInit(); PA_M(("----- Looking up '%s' -----", string)); while ((aP = paIterateNext(paList)) != NULL) { if (parNoP == NULL) { int len; PA_M(("Got option '%s' from itrration", aP->option)); if ((aP->option == NULL) || (aP->option[0] == 0)) continue; PA_M(("comparing '%s' to '%s'", string, aP->option)); len = strlen(aP->option); if (strict == STRICT) len = MAX(strlen(string), (unsigned int) len); if (len == 0) { LM_EXIT(); return NULL; } if (strncmp(aP->option, string, len) == 0) { if (foundP == NULL) { foundP = aP; foundNameLen = strlen(aP->option); } else if (strlen(aP->option) > (unsigned int) foundNameLen) { foundP = aP; foundNameLen = strlen(aP->option); } } } else if ((aP->what & PawParameter) == PawParameter) { if (aP->aux != 0) PA_W(("cant use this parameter")); else { aP->aux = 1; LM_EXIT(); return aP; } } else PA_M(("skipping option '%s'", aP->option)); } PA_M(("----- returning foundP ... -----")); LM_EXIT(); return foundP; }
/* **************************************************************************** * * paRcFileParse - parse startup file */ int paRcFileParse(void) { char dir[1024]; char path[1024]; char line[512]; int lineNo = 0; FILE* fP; char w[512]; LM_ENTRY(); if ((paRcFileName == NULL) || (paRcFileName[0] == 0)) { LM_EXIT(); return 0; } if (dirFind(dir, sizeof(dir)) == 0) { LM_T(LmtPaRcFile, ("RC file '%s' found in directory '%s'", paRcFileName, dir)); } else { return 0; } snprintf(path, sizeof(path), "%s/%s", dir, paRcFileName); if ((fP = fopen(path, "r")) == NULL) { LM_RE(-1, ("error opening RC file '%s': %s", path, strerror(errno))); } LM_T(LmtPaRcFile, ("parsing RC file %s", path)); while (fgets(line, sizeof(line), fP) != NULL) { char* delim; char* var; char* val; PaiArgument* aP; bool varFound; char envVarName[128]; ++lineNo; LM_T(LmtPaRcFile, ("got line %d", lineNo)); newlineStrip(line); LM_T(LmtPaRcFile, ("got line %d", lineNo)); commentStrip(line, '#'); LM_T(LmtPaRcFile, ("got line %d", lineNo)); baWsStrip(line); LM_T(LmtPaRcFile, ("got line %d", lineNo)); if (line[0] == 0) { continue; } LM_T(LmtPaRcFile, ("got line %d", lineNo)); delim = strchr(line, '='); if (delim == NULL) { char w[512]; snprintf(w, sizeof(w), "%s[%d]: no delimiter found", path, lineNo); PA_WARNING(PasParseError, w); continue; } *delim = 0; var = line; val = &delim[1]; baWsStrip(var); baWsStrip(val); if (var[0] == 0) { fclose(fP); LM_RE(-1, ("%s[%d]: no variable ...", path, lineNo)); } if (val[0] == 0) { fclose(fP); LM_RE(-1, ("%s[%d]: no value for variable %s", path, lineNo, var)); } varFound = false; paIterateInit(); while ((aP = paIterateNext(paiList)) != NULL) { paEnvName(aP, envVarName, sizeof(envVarName)); if (strcmp(var, envVarName) == 0) { aP->from = PafRcFile; LM_T(LmtPaRcFileVal, ("got value '%s' for %s", val, envVarName)); varFound = true; break; } } if (varFound == false) { char w[512]; snprintf(w, sizeof(w), "%s[%d]: variable '%s' not recognized", path, lineNo, var); PA_WARNING(PasNoSuchVariable, w); continue; } switch (aP->type) { case PaString: strcpy((char*) aP->varP, val); break; case PaBoolean: if ((strcmp(val, "TRUE") == 0) || (strcmp(val, "ON") == 0) || (strcmp(val, "yes") == 0) || (strcmp(val, "1") == 0)) *((bool*) (int64_t) aP->varP) = true; else if ((strcmp(val, "FALSE") == 0) || (strcmp(val, "OFF") == 0) || (strcmp(val, "no") == 0) || (strcmp(val, "0") == 0)) *((bool*) (int64_t) aP->varP) = false; else { snprintf(w, sizeof(w), "bad value '%s' for boolean variable %s", val, envVarName); PA_WARNING(PasNoSuchBooleanValue, w); } break; case PaSList: case PaIList: LM_TODO(("lists ...")); break; case PaInt: case PaIntU: *((int64_t*) aP->varP) = baStoi(val); break; case PaShort: case PaShortU: *((int16_t*) (int64_t) aP->varP) = baStoi(val); break; case PaFloat: *((float*) (int64_t) aP->varP) = baStof(val); break; case PaDouble: *((double*) (int64_t) aP->varP) = baStod(val); break; case PaChar: case PaCharU: *((char*) (int64_t) aP->varP) = baStoi(val); break; default: snprintf(w, sizeof(w), "bad type %d for variable %s", aP->type, envVarName); PA_WARNING(PasNoSuchType, w); } } fclose(fP); return 0; }
/* **************************************************************************** * * paArgInit - */ static int paArgInit(PaArgument* paList) { PaiArgument* aP; int parNo = 0; int ix = 0; int args = 0; while (paList[ix].type != PaLastArg) { ++args; ++ix; } paiList = (PaiArgument*) calloc(args + 1, sizeof(PaiArgument)); if (paiList == NULL) { PA_E(("Error allocating room for %d options", args)); exit(1); } PA_M(("Allocated room for %d args (plus one)", args)); for (ix = 0; ix < args + 1; ix++) { PA_M(("Copying arg %d", ix)); memcpy(&paiList[ix], &paList[ix], sizeof(paList[ix])); paiList[ix].isBuiltin = false; } paIterateInit(); while ((aP = paIterateNext(paiList)) != NULL) { char envVarName[128]; /* Set argument to be unused */ aP->used = 0; aP->hasDefault = true; aP->hasMinLimit = true; aP->hasMaxLimit = true; aP->aux = 0; /* Set the value to come from nowhere */ aP->from = PafUnchanged; if ((aP->option != NULL) && (aP->option[0] == 0)) { aP->option = NULL; } if ((aP->envName != NULL) && (aP->envName[0] == 0)) { aP->envName = NULL; } if ((aP->envName != NULL) && ((aP->envName[0] == ' ') || (aP->envName[0] == '\t'))) { char w[512]; snprintf(w, sizeof(w), "%s", "found an item with var name starting with whitespace - forbidden"); PA_WARNING(PasVarNameWs, w); continue; } /* Set the name of the argument */ if (aP->option == NULL) { if (aP->envName == NULL) { snprintf(aP->name, sizeof(aP->name), "parameter %d", ++parNo); aP->what = PawParameter; } else { char envVarName[128]; snprintf(aP->name, sizeof(aP->name), "variable/parameter %s", paEnvName(aP, envVarName, sizeof(envVarName))); aP->what = PawVariable; } } else if ((aP->option[0] == ' ') && (aP->option[1] == 0)) { ++parNo; if (aP->envName == NULL) { snprintf(aP->name, sizeof(aP->name), "parameter %d", parNo); aP->what = PawParameter; } else { char envVarName[128]; snprintf(aP->name, sizeof(aP->name), "parameter %s", paEnvName(aP, envVarName, sizeof(envVarName))); aP->what = PawVariable | PawParameter; } } else { if (aP->envName == NULL) { snprintf(aP->name, sizeof(aP->name), "option '%s'", aP->option); aP->what = PawOption; } else { snprintf(aP->name, sizeof(aP->name), "option '%s'", aP->option); aP->what = PawOption | PawVariable; } } if (optionNameDuplicated((char*) aP->option, ix) == true) { char w[512]; snprintf(w, sizeof(w), "%s (%s) duplicated in source code", aP->name, aP->description); PA_WARNING(PasOptionNameDuplicated, w); aP->removed = true; } paEnvName(aP, envVarName, sizeof(envVarName)); if (envNameDuplicated(envVarName, ix) == true) { char w[512]; snprintf(w, sizeof(w), "Env var '%s' (%s) duplicated in source code", envVarName, aP->description); PA_WARNING(PasEnvNameDuplicated, w); aP->removed = true; } ++ix; } return 0; }
/* **************************************************************************** * * paExtendedUsage - print extended synopsis */ void paExtendedUsage(void) { char* spacePad; char string[80]; PaiArgument* aP; int optNameMaxLen = 0; int varNameMaxLen = 0; int valsMaxLen = 0; char format[64]; char progNAME[128]; bool firstLine = true; snprintf(progNAME, sizeof(progNAME), "Extended Usage: %s ", progName); spacePad = (char*) strdup(progNAME); memset(spacePad, 0x20202020, strlen(spacePad)); /* replace progNAME */ PA_M(("-------------- Preparing list for Extended usage -----------------")); paIterateInit(); while ((aP = paIterateNext(paiList)) != NULL) { char name[128]; char vals[128]; char defVal[20]; char minVal[20]; char maxVal[20]; char realVal[80]; char out[256]; char out2[256]; PA_M(("processing '%s' for extended usage\n", aP->name)); /* 1. Option Name */ memset(name, 0, sizeof(name)); if (PA_IS_OPTION(aP) && (aP->sort == PaOpt)) { snprintf(name, sizeof(name), "[%s]", paFullName(aP, string, sizeof(string))); } else if (PA_IS_OPTION(aP) && (aP->sort == PaReq)) { snprintf(name, sizeof(name), "%s", paFullName(aP, string, sizeof(string))); } else if (PA_IS_PARAMETER(aP) && (aP->sort == PaOpt)) { snprintf(name, sizeof(name), "(%s)", aP->description); } else if (PA_IS_PARAMETER(aP) && (aP->sort == PaReq)) { snprintf(name, sizeof(name), "[%s]", aP->description); } optNameMaxLen = MAX(strlen(name), (unsigned int) optNameMaxLen); /* 2. Variable Name */ memset(name, 0, sizeof(name)); if (PA_IS_VARIABLE(aP)) { paEnvName(aP, name, sizeof(name)); varNameMaxLen = MAX(strlen(name), (unsigned int) varNameMaxLen); } /* 3. Values */ getApVals(aP, defVal, sizeof(defVal), minVal, sizeof(minVal), maxVal, sizeof(maxVal), realVal, sizeof(realVal)); if (aP->hasDefault == false) { snprintf(name, sizeof(name), "%s", realVal); } else { snprintf(name, sizeof(name), "%s /%s/", realVal, defVal); } if ((aP->hasMinLimit == false) && (aP->hasMaxLimit == false)) { snprintf(vals, sizeof(vals), "%s", name); } else if (aP->hasMinLimit == false) { snprintf(vals, sizeof(vals), "%s <= %s", name, escape(out, maxVal)); } else if (aP->hasMaxLimit == false) { snprintf(vals, sizeof(vals), "%s >= %s", name, escape(out, minVal)); } else { snprintf(vals, sizeof(vals), "%s <= %s <= %s", escape(out, minVal), name, escape(out2, maxVal)); } valsMaxLen = MAX(strlen(vals), (unsigned int) valsMaxLen); } snprintf(format, sizeof(format), "%%-%ds %%-%ds %%-%ds %%-%ds %%s\n", (int) strlen(progName) + 1, optNameMaxLen + 2, varNameMaxLen + 2, valsMaxLen + 2); // paLogOn = true; paIterateInit(); while ((aP = paIterateNext(paiList)) != NULL) { char optName[128]; char varName[128]; char vals[128]; char from[128]; char defVal[20]; char minVal[20]; char maxVal[20]; char realVal[80]; char s[512]; if (aP->sort == PaHid) { PA_M(("skipping hidden option '%s'", aP->option)); continue; } /* 1. Option Name */ if (PA_IS_OPTION(aP) && (aP->sort == PaOpt)) { snprintf(optName, sizeof(optName), "[%s]", paFullName(aP, string, sizeof(string))); } else if (PA_IS_OPTION(aP) && (aP->sort == PaReq)) { snprintf(optName, sizeof(optName), "%s", paFullName(aP, string, sizeof(string))); } else if (PA_IS_PARAMETER(aP) && (aP->sort == PaOpt)) { snprintf(optName, sizeof(optName), "(%s)", aP->description); } else if (PA_IS_PARAMETER(aP) && (aP->sort == PaReq)) { snprintf(optName, sizeof(optName), "[%s]", aP->description); } else { snprintf(optName, sizeof(optName), " "); } /* 2. variable name */ if (PA_IS_VARIABLE(aP)) { paEnvName(aP, varName, sizeof(varName)); } else { snprintf(varName, sizeof(varName), " "); } /* 3. Limits */ if ((aP->type != PaSList) && (aP->type != PaIList)) { char valWithDef[128]; char fromN[64]; getApVals(aP, defVal, sizeof(defVal), minVal, sizeof(minVal), maxVal, sizeof(maxVal), realVal, sizeof(realVal)); if (aP->hasDefault == false) { snprintf(valWithDef, sizeof(valWithDef), "%s", realVal); } else { snprintf(valWithDef, sizeof(valWithDef), "%s /%s/", realVal, defVal); } if ((aP->hasMinLimit == false) && (aP->hasMaxLimit == false)) { snprintf(vals, sizeof(vals), "%s", valWithDef); } else if (aP->hasMinLimit == false) { snprintf(vals, sizeof(vals), "%s <= %s", valWithDef, maxVal); } else if (aP->hasMaxLimit == false) { snprintf(vals, sizeof(vals), "%s >= %s", valWithDef, minVal); } else { snprintf(vals, sizeof(vals), "%s <= %s <= %s", minVal, valWithDef, maxVal); } snprintf(from, sizeof(from), " (%s)", paFromName(aP, fromN, sizeof(fromN))); } else { snprintf(vals, sizeof(vals), " "); snprintf(from, sizeof(from), " "); } snprintf(s, sizeof(s), format, (firstLine)? progNAME : spacePad, optName, varName, vals, from); strncat(paResultString, s, sizeof(paResultString) - 1); firstLine = false; } // paLogOn = false; strncat(paResultString, "\r", sizeof(paResultString) - 1); free(spacePad); printf("%s\n", paResultString); exit(1); }
/* **************************************************************************** * * paUsage - print synopsis (to file pointer or to paResultString) */ void paUsage(void) { char* spacePad; char string[512]; char s[1024]; PaiArgument* aP; int ix = -1; bool firstUserOptionFound = false; LM_T(LmtPaUsage, ("presenting usage")); spacePad = (char*) strdup(progName); memset(spacePad, 0x20202020, strlen(spacePad)); /* replace progName */ if (paUsageProgName != NULL) { snprintf(s, sizeof(s), "Usage: %s ", paUsageProgName); } else { snprintf(s, sizeof(s), "Usage: %s ", progName); } strncat(paResultString, s, sizeof(paResultString) - 1); // paLogOn = true; paIterateInit(); PA_M(("------------- presenting usage -------------")); bool firstTime = true; while ((aP = paIterateNext(paiList)) != NULL) { char xName[512]; PA_M(("Got option '%s'", aP->option)); ++ix; if (aP->sort == PaHid) { continue; } if ((aP->isBuiltin == true) && (aP->includeInUsage == false)) { continue; } if (!firstTime) { snprintf(s, sizeof(s), "%s ", spacePad); /* 8 spaces for "Usage: " */ strncat(paResultString, s, sizeof(paResultString) - 1); } firstTime = false; if ((aP->isBuiltin == false) && (firstUserOptionFound == false)) { firstUserOptionFound = true; strncat(paResultString, "\n", sizeof(paResultString) - 1 - strlen(paResultString)); strncat(paResultString, spacePad, sizeof(paResultString) - 1 - strlen(paResultString)); strncat(paResultString, " ", sizeof(paResultString) - 1 - strlen(paResultString)); } if (PA_IS_OPTION(aP) && (aP->sort == PaOpt)) { snprintf(xName, sizeof(xName), "[%s]", paFullName(aP, string, sizeof(string))); } else if (PA_IS_OPTION(aP) && (aP->sort == PaReq)) { snprintf(xName, sizeof(xName), "%s", paFullName(aP, string, sizeof(string))); } else if (PA_IS_PARAMETER(aP) && (aP->sort == PaOpt)) { snprintf(xName, sizeof(xName), "[parameter: %s]", aP->description); } else if (PA_IS_PARAMETER(aP) && (aP->sort == PaReq)) { snprintf(xName, sizeof(xName), "parameter: %s", aP->description); } else { snprintf(xName, sizeof(xName), " "); } snprintf(s, sizeof(s), " %s\n", xName); strncat(paResultString, s, sizeof(paResultString) - 1); PA_M(("parsed arg %d", ix)); } // paLogOn = false; free(spacePad); PA_M(("presenting usage")); printf("%s\n", paResultString); exit(0); }