| File: | src/hest/parseHest.c |
| Location: | line 1045, column 33 |
| Description: | Dereference of null pointer |
| 1 | /* | |||
| 2 | Teem: Tools to process and visualize scientific data and images . | |||
| 3 | Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago | |||
| 4 | Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann | |||
| 5 | Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah | |||
| 6 | ||||
| 7 | This library is free software; you can redistribute it and/or | |||
| 8 | modify it under the terms of the GNU Lesser General Public License | |||
| 9 | (LGPL) as published by the Free Software Foundation; either | |||
| 10 | version 2.1 of the License, or (at your option) any later version. | |||
| 11 | The terms of redistributing and/or modifying this software also | |||
| 12 | include exceptions to the LGPL that facilitate static linking. | |||
| 13 | ||||
| 14 | This library is distributed in the hope that it will be useful, | |||
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 17 | Lesser General Public License for more details. | |||
| 18 | ||||
| 19 | You should have received a copy of the GNU Lesser General Public License | |||
| 20 | along with this library; if not, write to Free Software Foundation, Inc., | |||
| 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| 22 | */ | |||
| 23 | ||||
| 24 | /* | |||
| 25 | learned: well duh: when you send arguments to printf(), they will | |||
| 26 | be evaluated before printf() sees them, so you can't use _hestIdent() | |||
| 27 | twice with differen values | |||
| 28 | */ | |||
| 29 | ||||
| 30 | #include "hest.h" | |||
| 31 | #include "privateHest.h" | |||
| 32 | ||||
| 33 | #include <string.h> | |||
| 34 | ||||
| 35 | #define ME((parm && parm->verbosity) ? me : "") ((parm && parm->verbosity) ? me : "") | |||
| 36 | ||||
| 37 | /* | |||
| 38 | ** _hestArgsInResponseFiles() | |||
| 39 | ** | |||
| 40 | ** returns the number of args that will be parsed from the response files. | |||
| 41 | ** The role of this function is solely to simplify the task of avoiding | |||
| 42 | ** memory leaks. By knowing exactly how many args we'll get in the response | |||
| 43 | ** file, then hestParse() can allocate its local argv[] for exactly as | |||
| 44 | ** long as it needs to be, and we can avoid using an airArray. The drawback | |||
| 45 | ** is that we open and read through the response files twice. Alas. | |||
| 46 | */ | |||
| 47 | int | |||
| 48 | _hestArgsInResponseFiles(int *argcP, int *nrfP, | |||
| 49 | const char **argv, char *err, | |||
| 50 | const hestParm *parm) { | |||
| 51 | FILE *file; | |||
| 52 | char me[]="_hestArgsInResponseFiles: ", line[AIR_STRLEN_HUGE(1024+1)], *pound; | |||
| 53 | int ai, len; | |||
| 54 | ||||
| 55 | *argcP = 0; | |||
| 56 | *nrfP = 0; | |||
| 57 | if (!parm->respFileEnable) { | |||
| 58 | /* don't do response files; we're done */ | |||
| 59 | return 0; | |||
| 60 | } | |||
| 61 | ||||
| 62 | ai = 0; | |||
| 63 | while (argv[ai]) { | |||
| 64 | if (parm->respFileFlag == argv[ai][0]) { | |||
| 65 | if (!(file = fopen(argv[ai]+1, "rb"))) { | |||
| 66 | /* can't open the indicated response file for reading */ | |||
| 67 | sprintf(err, "%scouldn't open \"%s\" for reading as response file",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't open \"%s\" for reading as response file" , ((parm && parm->verbosity) ? me : ""), argv[ai]+ 1) | |||
| 68 | ME, argv[ai]+1)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't open \"%s\" for reading as response file" , ((parm && parm->verbosity) ? me : ""), argv[ai]+ 1); | |||
| 69 | *argcP = 0; | |||
| 70 | *nrfP = 0; | |||
| 71 | return 1; | |||
| 72 | } | |||
| 73 | len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1)); | |||
| 74 | while (len > 0) { | |||
| 75 | if ( (pound = strchr(line, parm->respFileComment)) ) | |||
| 76 | *pound = '\0'; | |||
| 77 | airOneLinify(line); | |||
| 78 | *argcP += airStrntok(line, AIR_WHITESPACE" \t\n\r\v\f"); | |||
| 79 | len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1)); | |||
| 80 | } | |||
| 81 | fclose(file); | |||
| 82 | (*nrfP)++; | |||
| 83 | } | |||
| 84 | ai++; | |||
| 85 | } | |||
| 86 | return 0; | |||
| 87 | } | |||
| 88 | ||||
| 89 | /* | |||
| 90 | ** _hestResponseFiles() | |||
| 91 | ** | |||
| 92 | ** This function is badly named. Even if there are no response files, | |||
| 93 | ** even if response files are disabled, this is the function that | |||
| 94 | ** copies from the user's argc,argv to our local copy. | |||
| 95 | */ | |||
| 96 | int | |||
| 97 | _hestResponseFiles(char **newArgv, const char **oldArgv, | |||
| 98 | const hestParm *parm, airArray *pmop) { | |||
| 99 | char line[AIR_STRLEN_HUGE(1024+1)], *pound; | |||
| 100 | int len, newArgc, oldArgc, incr, ai; | |||
| 101 | FILE *file; | |||
| 102 | ||||
| 103 | newArgc = oldArgc = 0; | |||
| 104 | while(oldArgv[oldArgc]) { | |||
| 105 | if (parm->verbosity) { | |||
| 106 | printf("!%s:________ newArgc = %d, oldArgc = %d\n", | |||
| 107 | "dammit", newArgc, oldArgc); | |||
| 108 | _hestPrintArgv(newArgc, newArgv); | |||
| 109 | } | |||
| 110 | if (!parm->respFileEnable | |||
| 111 | || parm->respFileFlag != oldArgv[oldArgc][0]) { | |||
| 112 | /* nothing to do with a response file */ | |||
| 113 | newArgv[newArgc] = airStrdup(oldArgv[oldArgc]); | |||
| 114 | airMopAdd(pmop, newArgv[newArgc], airFree, airMopAlways); | |||
| 115 | newArgc += 1; | |||
| 116 | } | |||
| 117 | else { | |||
| 118 | /* It is a response file. Error checking on open-ability | |||
| 119 | should have been done by _hestArgsInResponseFiles() */ | |||
| 120 | file = fopen(oldArgv[oldArgc]+1, "rb"); | |||
| 121 | len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1)); | |||
| 122 | while (len > 0) { | |||
| 123 | if (parm->verbosity) | |||
| 124 | printf("_hestResponseFiles: line: |%s|\n", line); | |||
| 125 | if ( (pound = strchr(line, parm->respFileComment)) ) | |||
| 126 | *pound = '\0'; | |||
| 127 | if (parm->verbosity) | |||
| 128 | printf("_hestResponseFiles: -0-> line: |%s|\n", line); | |||
| 129 | airOneLinify(line); | |||
| 130 | incr = airStrntok(line, AIR_WHITESPACE" \t\n\r\v\f"); | |||
| 131 | if (parm->verbosity) | |||
| 132 | printf("_hestResponseFiles: -1-> line: |%s|, incr=%d\n", | |||
| 133 | line, incr); | |||
| 134 | airParseStrS(newArgv + newArgc, line, AIR_WHITESPACE" \t\n\r\v\f", incr, AIR_FALSE0); | |||
| 135 | for (ai=0; ai<incr; ai++) { | |||
| 136 | /* This time, we did allocate memory. We can use airFree and | |||
| 137 | not airFreeP because these will not be reset before mopping */ | |||
| 138 | airMopAdd(pmop, newArgv[newArgc+ai], airFree, airMopAlways); | |||
| 139 | } | |||
| 140 | len = airOneLine(file, line, AIR_STRLEN_HUGE(1024+1)); | |||
| 141 | newArgc += incr; | |||
| 142 | } | |||
| 143 | fclose(file); | |||
| 144 | } | |||
| 145 | oldArgc++; | |||
| 146 | if (parm->verbosity) { | |||
| 147 | _hestPrintArgv(newArgc, newArgv); | |||
| 148 | printf("!%s: ^^^^^^^ newArgc = %d, oldArgc = %d\n", | |||
| 149 | "dammit", newArgc, oldArgc); | |||
| 150 | } | |||
| 151 | } | |||
| 152 | newArgv[newArgc] = NULL((void*)0); | |||
| 153 | ||||
| 154 | return 0; | |||
| 155 | } | |||
| 156 | ||||
| 157 | /* | |||
| 158 | ** _hestPanic() | |||
| 159 | ** | |||
| 160 | ** all error checking on the given hest array itself (not the | |||
| 161 | ** command line to be parsed). Also, sets the "kind" field of | |||
| 162 | ** the opt struct | |||
| 163 | */ | |||
| 164 | int | |||
| 165 | _hestPanic(hestOpt *opt, char *err, const hestParm *parm) { | |||
| 166 | char me[]="_hestPanic: ", tbuff[AIR_STRLEN_HUGE(1024+1)], *sep; | |||
| 167 | int numvar, op, numOpts; | |||
| 168 | ||||
| 169 | numOpts = _hestNumOpts(opt); | |||
| 170 | numvar = 0; | |||
| 171 | for (op=0; op<numOpts; op++) { | |||
| 172 | opt[op].kind = _hestKind(opt + op); | |||
| 173 | if (!(AIR_IN_OP(airTypeUnknown, opt[op].type, airTypeLast)((airTypeUnknown) < (opt[op].type) && (opt[op].type ) < (airTypeLast)))) { | |||
| 174 | if (err) | |||
| 175 | sprintf(err, "%s!!!!!! opt[%d].type (%d) not in valid range [%d,%d]",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d].type (%d) not in valid range [%d,%d]" , ((parm && parm->verbosity) ? me : ""), op, opt[op ].type, airTypeUnknown+1, airTypeLast-1) | |||
| 176 | ME, op, opt[op].type, airTypeUnknown+1, airTypeLast-1)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d].type (%d) not in valid range [%d,%d]" , ((parm && parm->verbosity) ? me : ""), op, opt[op ].type, airTypeUnknown+1, airTypeLast-1); | |||
| 177 | else | |||
| 178 | fprintf(stderr__stderrp, "%s: panic 0\n", me); | |||
| 179 | return 1; | |||
| 180 | } | |||
| 181 | if (!( opt[op].valueP )) { | |||
| 182 | if (err) | |||
| 183 | sprintf(err, "%s!!!!!! opt[%d]'s valueP is NULL!", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s valueP is NULL!", ((parm && parm->verbosity) ? me : ""), op); | |||
| 184 | else | |||
| 185 | fprintf(stderr__stderrp, "%s: panic 0.5\n", me); | |||
| 186 | return 1; | |||
| 187 | } | |||
| 188 | if (-1 == opt[op].kind) { | |||
| 189 | if (err) | |||
| 190 | sprintf(err, "%s!!!!!! opt[%d]'s min (%d) and max (%d) incompatible",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s min (%d) and max (%d) incompatible" , ((parm && parm->verbosity) ? me : ""), op, opt[op ].min, opt[op].max) | |||
| 191 | ME, op, opt[op].min, opt[op].max)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s min (%d) and max (%d) incompatible" , ((parm && parm->verbosity) ? me : ""), op, opt[op ].min, opt[op].max); | |||
| 192 | else | |||
| 193 | fprintf(stderr__stderrp, "%s: panic 1\n", me); | |||
| 194 | return 1; | |||
| 195 | } | |||
| 196 | if (5 == opt[op].kind && !(opt[op].sawP)) { | |||
| 197 | if (err) | |||
| 198 | sprintf(err, "%s!!!!!! have multiple variable parameters, "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! have multiple variable parameters, " "but sawP is NULL", ((parm && parm->verbosity) ? me : "")) | |||
| 199 | "but sawP is NULL", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! have multiple variable parameters, " "but sawP is NULL", ((parm && parm->verbosity) ? me : "")); | |||
| 200 | else | |||
| 201 | fprintf(stderr__stderrp, "%s: panic 2\n", me); | |||
| 202 | return 1; | |||
| 203 | } | |||
| 204 | if (airTypeEnum == opt[op].type) { | |||
| 205 | if (!(opt[op].enm)) { | |||
| 206 | if (err) { | |||
| 207 | sprintf(err, "%s!!!!!! opt[%d] (%s) is type \"enum\", but no "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"enum\", but no " "airEnum pointer given", ((parm && parm->verbosity ) ? me : ""), op, opt[op].flag ? opt[op].flag : "?") | |||
| 208 | "airEnum pointer given", ME, op,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"enum\", but no " "airEnum pointer given", ((parm && parm->verbosity ) ? me : ""), op, opt[op].flag ? opt[op].flag : "?") | |||
| 209 | opt[op].flag ? opt[op].flag : "?")__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"enum\", but no " "airEnum pointer given", ((parm && parm->verbosity ) ? me : ""), op, opt[op].flag ? opt[op].flag : "?"); | |||
| 210 | } else { | |||
| 211 | fprintf(stderr__stderrp, "%s: panic 3\n", me); | |||
| 212 | } | |||
| 213 | return 1; | |||
| 214 | } | |||
| 215 | } | |||
| 216 | if (airTypeOther == opt[op].type) { | |||
| 217 | if (!(opt[op].CB)) { | |||
| 218 | if (err) { | |||
| 219 | sprintf(err, "%s!!!!!! opt[%d] (%s) is type \"other\", but no "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"other\", but no " "callbacks given", ((parm && parm->verbosity) ? me : ""), op, opt[op].flag ? opt[op].flag : "?") | |||
| 220 | "callbacks given", ME, op,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"other\", but no " "callbacks given", ((parm && parm->verbosity) ? me : ""), op, opt[op].flag ? opt[op].flag : "?") | |||
| 221 | opt[op].flag ? opt[op].flag : "?")__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] (%s) is type \"other\", but no " "callbacks given", ((parm && parm->verbosity) ? me : ""), op, opt[op].flag ? opt[op].flag : "?"); | |||
| 222 | } else { | |||
| 223 | fprintf(stderr__stderrp, "%s: panic 4\n", me); | |||
| 224 | } | |||
| 225 | return 1; | |||
| 226 | } | |||
| 227 | if (!( opt[op].CB->size > 0 )) { | |||
| 228 | if (err) | |||
| 229 | sprintf(err, "%s!!!!!! opt[%d]'s \"size\" (%d) invalid",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"size\" (%d) invalid", ((parm && parm->verbosity) ? me : ""), op, (int)( opt[op].CB->size)) | |||
| 230 | ME, op, (int)(opt[op].CB->size))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"size\" (%d) invalid", ((parm && parm->verbosity) ? me : ""), op, (int)( opt[op].CB->size)); | |||
| 231 | else | |||
| 232 | fprintf(stderr__stderrp, "%s: panic 5\n", me); | |||
| 233 | return 1; | |||
| 234 | } | |||
| 235 | if (!( opt[op].type )) { | |||
| 236 | if (err) | |||
| 237 | sprintf(err, "%s!!!!!! opt[%d]'s \"type\" is NULL",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"type\" is NULL", ((parm && parm->verbosity) ? me : ""), op) | |||
| 238 | ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"type\" is NULL", ((parm && parm->verbosity) ? me : ""), op); | |||
| 239 | else | |||
| 240 | fprintf(stderr__stderrp, "%s: panic 6\n", me); | |||
| 241 | return 1; | |||
| 242 | ||||
| 243 | } | |||
| 244 | if (!( opt[op].CB->parse )) { | |||
| 245 | if (err) | |||
| 246 | sprintf(err, "%s!!!!!! opt[%d]'s \"parse\" callback NULL", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d]'s \"parse\" callback NULL" , ((parm && parm->verbosity) ? me : ""), op); | |||
| 247 | else | |||
| 248 | fprintf(stderr__stderrp, "%s: panic 7\n", me); | |||
| 249 | return 1; | |||
| 250 | } | |||
| 251 | if (opt[op].CB->destroy && (sizeof(void*) != opt[op].CB->size)) { | |||
| 252 | if (err) | |||
| 253 | sprintf(err, "%s!!!!!! opt[%d] has a \"destroy\", but size isn't "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] has a \"destroy\", but size isn't " "sizeof(void*)", ((parm && parm->verbosity) ? me : ""), op) | |||
| 254 | "sizeof(void*)", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] has a \"destroy\", but size isn't " "sizeof(void*)", ((parm && parm->verbosity) ? me : ""), op); | |||
| 255 | else | |||
| 256 | fprintf(stderr__stderrp, "%s: panic 8\n", me); | |||
| 257 | return 1; | |||
| 258 | } | |||
| 259 | } | |||
| 260 | if (opt[op].flag) { | |||
| 261 | strcpy(tbuff, opt[op].flag)__builtin___strcpy_chk (tbuff, opt[op].flag, __builtin_object_size (tbuff, 2 > 1 ? 1 : 0)); | |||
| 262 | if (( sep = strchr(tbuff, parm->multiFlagSep) )) { | |||
| 263 | *sep = '\0'; | |||
| 264 | if (!( strlen(tbuff) && strlen(sep+1) )) { | |||
| 265 | if (err) | |||
| 266 | sprintf(err, "%s!!!!!! either short (\"%s\") or long (\"%s\") flag"__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! either short (\"%s\") or long (\"%s\") flag" " of opt[%d] is zero length", ((parm && parm->verbosity ) ? me : ""), tbuff, sep+1, op) | |||
| 267 | " of opt[%d] is zero length", ME, tbuff, sep+1, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! either short (\"%s\") or long (\"%s\") flag" " of opt[%d] is zero length", ((parm && parm->verbosity ) ? me : ""), tbuff, sep+1, op); | |||
| 268 | else | |||
| 269 | fprintf(stderr__stderrp, "%s: panic 9\n", me); | |||
| 270 | return 1; | |||
| 271 | } | |||
| 272 | } | |||
| 273 | else { | |||
| 274 | if (!strlen(opt[op].flag)) { | |||
| 275 | if (err) | |||
| 276 | sprintf(err, "%s!!!!!! opt[%d].flag is zero length",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d].flag is zero length", ((parm && parm->verbosity) ? me : ""), op) | |||
| 277 | ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d].flag is zero length", ((parm && parm->verbosity) ? me : ""), op); | |||
| 278 | else | |||
| 279 | fprintf(stderr__stderrp, "%s: panic 10\n", me); | |||
| 280 | return 1; | |||
| 281 | } | |||
| 282 | } | |||
| 283 | if (4 == opt[op].kind) { | |||
| 284 | if (!opt[op].dflt) { | |||
| 285 | if (err) | |||
| 286 | sprintf(err, "%s!!!!!! flagged single variable parameter must "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter must " "specify a default", ((parm && parm->verbosity) ? me : "")) | |||
| 287 | "specify a default", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter must " "specify a default", ((parm && parm->verbosity) ? me : "")); | |||
| 288 | else | |||
| 289 | fprintf(stderr__stderrp, "%s: panic 11\n", me); | |||
| 290 | return 1; | |||
| 291 | } | |||
| 292 | if (!strlen(opt[op].dflt)) { | |||
| 293 | if (err) | |||
| 294 | sprintf(err, "%s!!!!!! flagged single variable parameter default "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter default " "must be non-zero length", ((parm && parm->verbosity ) ? me : "")) | |||
| 295 | "must be non-zero length", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! flagged single variable parameter default " "must be non-zero length", ((parm && parm->verbosity ) ? me : "")); | |||
| 296 | else | |||
| 297 | fprintf(stderr__stderrp, "%s: panic 12\n", me); | |||
| 298 | return 1; | |||
| 299 | } | |||
| 300 | } | |||
| 301 | /* | |||
| 302 | sprintf(tbuff, "-%s", opt[op].flag); | |||
| 303 | if (1 == sscanf(tbuff, "%f", &tmpF)) { | |||
| 304 | if (err) | |||
| 305 | sprintf(err, "%s!!!!!! opt[%d].flag (\"%s\") is numeric, bad news", | |||
| 306 | ME, op, opt[op].flag); | |||
| 307 | return 1; | |||
| 308 | } | |||
| 309 | */ | |||
| 310 | } | |||
| 311 | if (1 == opt[op].kind) { | |||
| 312 | if (!opt[op].flag) { | |||
| 313 | if (err) | |||
| 314 | sprintf(err, "%s!!!!!! flags must have flags", ME)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! flags must have flags", ((parm && parm->verbosity) ? me : "")); | |||
| 315 | else | |||
| 316 | fprintf(stderr__stderrp, "%s: panic 13\n", me); | |||
| 317 | return 1; | |||
| 318 | } | |||
| 319 | } | |||
| 320 | else { | |||
| 321 | if (!opt[op].name) { | |||
| 322 | if (err) | |||
| 323 | sprintf(err, "%s!!!!!! opt[%d] isn't a flag: must have \"name\"",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] isn't a flag: must have \"name\"" , ((parm && parm->verbosity) ? me : ""), op) | |||
| 324 | ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] isn't a flag: must have \"name\"" , ((parm && parm->verbosity) ? me : ""), op); | |||
| 325 | else | |||
| 326 | fprintf(stderr__stderrp, "%s: panic 14\n", me); | |||
| 327 | return 1; | |||
| 328 | } | |||
| 329 | } | |||
| 330 | if (4 == opt[op].kind && !opt[op].dflt) { | |||
| 331 | if (err) | |||
| 332 | sprintf(err, "%s!!!!!! opt[%d] is single variable parameter, but "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] is single variable parameter, but " "no default set", ((parm && parm->verbosity) ? me : ""), op) | |||
| 333 | "no default set", ME, op)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! opt[%d] is single variable parameter, but " "no default set", ((parm && parm->verbosity) ? me : ""), op); | |||
| 334 | else | |||
| 335 | fprintf(stderr__stderrp, "%s: panic 15\n", me); | |||
| 336 | return 1; | |||
| 337 | } | |||
| 338 | numvar += ((int)opt[op].min < _hestMax(opt[op].max) && (NULL((void*)0) == opt[op].flag)); /* HEY scrutinize casts */ | |||
| 339 | } | |||
| 340 | if (numvar > 1) { | |||
| 341 | if (err) | |||
| 342 | sprintf(err, "%s!!!!!! can't have %d unflagged min<max opts, only one",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! can't have %d unflagged min<max opts, only one" , ((parm && parm->verbosity) ? me : ""), numvar) | |||
| 343 | ME, numvar)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s!!!!!! can't have %d unflagged min<max opts, only one" , ((parm && parm->verbosity) ? me : ""), numvar); | |||
| 344 | else | |||
| 345 | fprintf(stderr__stderrp, "%s: panic 16\n", me); | |||
| 346 | return 1; | |||
| 347 | } | |||
| 348 | return 0; | |||
| 349 | } | |||
| 350 | ||||
| 351 | int | |||
| 352 | _hestErrStrlen(const hestOpt *opt, int argc, const char **argv) { | |||
| 353 | int a, numOpts, ret, other; | |||
| 354 | ||||
| 355 | ret = 0; | |||
| 356 | numOpts = _hestNumOpts(opt); | |||
| 357 | other = AIR_FALSE0; | |||
| 358 | if (argv) { | |||
| 359 | for (a=0; a<argc; a++) { | |||
| 360 | ret = AIR_MAX(ret, (int)airStrlen(argv[a]))((ret) > ((int)airStrlen(argv[a])) ? (ret) : ((int)airStrlen (argv[a]))); | |||
| 361 | } | |||
| 362 | } | |||
| 363 | for (a=0; a<numOpts; a++) { | |||
| 364 | ret = AIR_MAX(ret, (int)airStrlen(opt[a].flag))((ret) > ((int)airStrlen(opt[a].flag)) ? (ret) : ((int)airStrlen (opt[a].flag))); | |||
| 365 | ret = AIR_MAX(ret, (int)airStrlen(opt[a].name))((ret) > ((int)airStrlen(opt[a].name)) ? (ret) : ((int)airStrlen (opt[a].name))); | |||
| 366 | other |= opt[a].type == airTypeOther; | |||
| 367 | } | |||
| 368 | for (a=airTypeUnknown+1; a<airTypeLast; a++) { | |||
| 369 | ret = AIR_MAX(ret, (int)airStrlen(airTypeStr[a]))((ret) > ((int)airStrlen(airTypeStr[a])) ? (ret) : ((int)airStrlen (airTypeStr[a]))); | |||
| 370 | } | |||
| 371 | if (other) { | |||
| 372 | /* the callback's error() function may sprintf an error message | |||
| 373 | into a buffer which is size AIR_STRLEN_HUGE */ | |||
| 374 | ret += AIR_STRLEN_HUGE(1024+1); | |||
| 375 | } | |||
| 376 | ret += 4 * 12; /* as many as 4 ints per error message */ | |||
| 377 | ret += 257; /* function name and text of hest's error message */ | |||
| 378 | ||||
| 379 | return ret; | |||
| 380 | } | |||
| 381 | ||||
| 382 | /* | |||
| 383 | ** _hestExtractFlagged() | |||
| 384 | ** | |||
| 385 | ** extracts the parameters associated with all flagged options from the | |||
| 386 | ** given argc and argv, storing them in prms[], recording the number | |||
| 387 | ** of parameters in nprm[], and whether or not the flagged option appeared | |||
| 388 | ** in appr[]. | |||
| 389 | ** | |||
| 390 | ** The "saw" information is not set here, since it is better set | |||
| 391 | ** at value parsing time, which happens after defaults are enstated. | |||
| 392 | */ | |||
| 393 | int | |||
| 394 | _hestExtractFlagged(char **prms, unsigned int *nprm, int *appr, | |||
| 395 | int *argcP, char **argv, | |||
| 396 | hestOpt *opt, | |||
| 397 | char *err, const hestParm *parm, airArray *pmop) { | |||
| 398 | char me[]="_hestExtractFlagged: ", ident1[AIR_STRLEN_HUGE(1024+1)], | |||
| 399 | ident2[AIR_STRLEN_HUGE(1024+1)]; | |||
| 400 | int a, np, flag, endflag, numOpts, op; | |||
| 401 | ||||
| 402 | a = 0; | |||
| 403 | if (parm->verbosity) | |||
| 404 | printf("!%s: *argcP = %d\n", me, *argcP); | |||
| 405 | while (a<=*argcP-1) { | |||
| 406 | if (parm->verbosity) | |||
| 407 | printf("!%s: a = %d -> argv[a] = %s\n", me, a, argv[a]); | |||
| 408 | flag = _hestWhichFlag(opt, argv[a], parm); | |||
| 409 | if (parm->verbosity) | |||
| 410 | printf("!%s: A: a = %d -> flag = %d\n", me, a, flag); | |||
| 411 | if (!(0 <= flag)) { | |||
| 412 | /* not a flag, move on */ | |||
| 413 | a++; | |||
| 414 | continue; | |||
| 415 | } | |||
| 416 | /* see if we can associate some parameters with the flag */ | |||
| 417 | np = 0; | |||
| 418 | endflag = 0; | |||
| 419 | while (np < _hestMax(opt[flag].max) && | |||
| 420 | a+np+1 <= *argcP-1 && | |||
| 421 | -1 == (endflag = _hestWhichFlag(opt, argv[a+np+1], parm))) { | |||
| 422 | np++; | |||
| 423 | if (parm->verbosity) | |||
| 424 | printf("!%s: np --> %d with endflag = %d\n", me, np, endflag); | |||
| 425 | } | |||
| 426 | /* we stopped because we got the max number of parameters, or | |||
| 427 | because we hit the end of the command line, or | |||
| 428 | because _hestWhichFlag() returned something other than -1, | |||
| 429 | which means it returned -2, or a valid option index. If | |||
| 430 | we stopped because of _hestWhichFlag()'s return value, | |||
| 431 | endflag has been set to that return value */ | |||
| 432 | if (parm->verbosity) | |||
| 433 | printf("!%s: B: np = %d; endflag = %d\n", me, np, endflag); | |||
| 434 | if (np < (int)opt[flag].min) { /* HEY scrutinize casts */ | |||
| 435 | /* didn't get minimum number of parameters */ | |||
| 436 | if (!( a+np+1 <= *argcP-1 )) { | |||
| 437 | sprintf(err, "%shit end of line before getting %d parameter%s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit end of line before getting %d parameter%s " "for %s (got %d)", ((parm && parm->verbosity) ? me : ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent (ident1, opt+flag, parm, 1), np) | |||
| 438 | "for %s (got %d)",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit end of line before getting %d parameter%s " "for %s (got %d)", ((parm && parm->verbosity) ? me : ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent (ident1, opt+flag, parm, 1), np) | |||
| 439 | ME, opt[flag].min, opt[flag].min > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit end of line before getting %d parameter%s " "for %s (got %d)", ((parm && parm->verbosity) ? me : ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent (ident1, opt+flag, parm, 1), np) | |||
| 440 | _hestIdent(ident1, opt+flag, parm, AIR_TRUE), np)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit end of line before getting %d parameter%s " "for %s (got %d)", ((parm && parm->verbosity) ? me : ""), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent (ident1, opt+flag, parm, 1), np); | |||
| 441 | } | |||
| 442 | else { | |||
| 443 | sprintf(err, "%shit %s before getting %d parameter%s for %s (got %d)",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), _hestIdent (ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np) | |||
| 444 | ME, _hestIdent(ident1, opt+endflag, parm, AIR_FALSE),__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), _hestIdent (ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np) | |||
| 445 | opt[flag].min, opt[flag].min > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), _hestIdent (ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np) | |||
| 446 | _hestIdent(ident2, opt+flag, parm, AIR_FALSE), np)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%shit %s before getting %d parameter%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), _hestIdent (ident1, opt+endflag, parm, 0), opt[flag].min, opt[flag].min > 1 ? "s" : "", _hestIdent(ident2, opt+flag, parm, 0), np); | |||
| 447 | } | |||
| 448 | return 1; | |||
| 449 | } | |||
| 450 | nprm[flag] = np; | |||
| 451 | if (parm->verbosity) { | |||
| 452 | printf("!%s:________ a=%d, *argcP = %d -> flag = %d\n", | |||
| 453 | me, a, *argcP, flag); | |||
| 454 | _hestPrintArgv(*argcP, argv); | |||
| 455 | } | |||
| 456 | /* lose the flag argument */ | |||
| 457 | free(_hestExtract(argcP, argv, a, 1)); | |||
| 458 | /* extract the args after the flag */ | |||
| 459 | if (appr[flag]) { | |||
| 460 | airMopSub(pmop, prms[flag], airFree); | |||
| 461 | prms[flag] = (char *)airFree(prms[flag]); | |||
| 462 | } | |||
| 463 | prms[flag] = _hestExtract(argcP, argv, a, nprm[flag]); | |||
| 464 | airMopAdd(pmop, prms[flag], airFree, airMopAlways); | |||
| 465 | appr[flag] = AIR_TRUE1; | |||
| 466 | if (-2 == endflag) { | |||
| 467 | /* we should lose the end-of-variable-parameter marker */ | |||
| 468 | free(_hestExtract(argcP, argv, a, 1)); | |||
| 469 | } | |||
| 470 | if (parm->verbosity) { | |||
| 471 | _hestPrintArgv(*argcP, argv); | |||
| 472 | printf("!%s:^^^^^^^^ *argcP = %d\n", me, *argcP); | |||
| 473 | printf("!%s: prms[%d] = %s\n", me, flag, | |||
| 474 | prms[flag] ? prms[flag] : "(null)"); | |||
| 475 | } | |||
| 476 | } | |||
| 477 | ||||
| 478 | /* make sure that flagged options without default were given */ | |||
| 479 | numOpts = _hestNumOpts(opt); | |||
| 480 | for (op=0; op<numOpts; op++) { | |||
| 481 | if (1 != opt[op].kind && opt[op].flag && !opt[op].dflt && !appr[op]) { | |||
| 482 | sprintf(err, "%sdidn't get required %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdidn't get required %s", ((parm && parm->verbosity) ? me : ""), _hestIdent(ident1, opt+op, parm , 0)) | |||
| 483 | ME, _hestIdent(ident1, opt+op, parm, AIR_FALSE))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdidn't get required %s", ((parm && parm->verbosity) ? me : ""), _hestIdent(ident1, opt+op, parm , 0)); | |||
| 484 | return 1; | |||
| 485 | } | |||
| 486 | } | |||
| 487 | ||||
| 488 | return 0; | |||
| 489 | } | |||
| 490 | ||||
| 491 | int | |||
| 492 | _hestNextUnflagged(int op, hestOpt *opt, int numOpts) { | |||
| 493 | ||||
| 494 | for(; op<=numOpts-1; op++) { | |||
| 495 | if (!opt[op].flag) | |||
| 496 | break; | |||
| 497 | } | |||
| 498 | return op; | |||
| 499 | } | |||
| 500 | ||||
| 501 | int | |||
| 502 | _hestExtractUnflagged(char **prms, unsigned int *nprm, | |||
| 503 | int *argcP, char **argv, | |||
| 504 | hestOpt *opt, | |||
| 505 | char *err, const hestParm *parm, airArray *pmop) { | |||
| 506 | char me[]="_hestExtractUnflagged: ", ident[AIR_STRLEN_HUGE(1024+1)]; | |||
| 507 | int nvp, np, op, unflag1st, unflagVar, numOpts; | |||
| 508 | ||||
| 509 | numOpts = _hestNumOpts(opt); | |||
| 510 | unflag1st = _hestNextUnflagged(0, opt, numOpts); | |||
| 511 | if (numOpts == unflag1st) { | |||
| 512 | /* no unflagged options; we're done */ | |||
| 513 | return 0; | |||
| 514 | } | |||
| 515 | ||||
| 516 | for (unflagVar = unflag1st; | |||
| 517 | unflagVar != numOpts; | |||
| 518 | unflagVar = _hestNextUnflagged(unflagVar+1, opt, numOpts)) { | |||
| 519 | if ((int)opt[unflagVar].min < _hestMax(opt[unflagVar].max)) /* HEY scrutinize casts */ | |||
| 520 | break; | |||
| 521 | } | |||
| 522 | /* now, if there is a variable parameter unflagged opt, unflagVar is its | |||
| 523 | index in opt[], or else unflagVar is numOpts */ | |||
| 524 | ||||
| 525 | /* grab parameters for all unflagged opts before opt[t] */ | |||
| 526 | for (op = _hestNextUnflagged(0, opt, numOpts); | |||
| 527 | op < unflagVar; | |||
| 528 | op = _hestNextUnflagged(op+1, opt, numOpts)) { | |||
| 529 | /* printf("!%s: op = %d; unflagVar = %d\n", me, op, unflagVar); */ | |||
| 530 | np = opt[op].min; /* min == max */ | |||
| 531 | if (!(np <= *argcP)) { | |||
| 532 | sprintf(err, "%sdon't have %d parameter%s %s%s%sfor %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv [0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm , 1)) | |||
| 533 | ME, np, np > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv [0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm , 1)) | |||
| 534 | argv[0] ? "starting at \"" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv [0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm , 1)) | |||
| 535 | argv[0] ? argv[0] : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv [0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm , 1)) | |||
| 536 | argv[0] ? "\" " : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv [0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm , 1)) | |||
| 537 | _hestIdent(ident, opt+op, parm, AIR_TRUE))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s %s%s%sfor %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", argv[0] ? "starting at \"" : "", argv[0] ? argv [0] : "", argv[0] ? "\" " : "", _hestIdent(ident, opt+op, parm , 1)); | |||
| 538 | return 1; | |||
| 539 | } | |||
| 540 | prms[op] = _hestExtract(argcP, argv, 0, np); | |||
| 541 | airMopAdd(pmop, prms[op], airFree, airMopAlways); | |||
| 542 | nprm[op] = np; | |||
| 543 | } | |||
| 544 | /* | |||
| 545 | _hestPrintArgv(*argcP, argv); | |||
| 546 | */ | |||
| 547 | /* we skip over the variable parameter unflagged option, subtract from *argcP | |||
| 548 | the number of parameters in all the opts which follow it, in order to get | |||
| 549 | the number of parameters in the sole variable parameter option, | |||
| 550 | store this in nvp */ | |||
| 551 | nvp = *argcP; | |||
| 552 | for (op = _hestNextUnflagged(unflagVar+1, opt, numOpts); | |||
| 553 | op < numOpts; | |||
| 554 | op = _hestNextUnflagged(op+1, opt, numOpts)) { | |||
| 555 | nvp -= opt[op].min; /* min == max */ | |||
| 556 | } | |||
| 557 | if (nvp < 0) { | |||
| 558 | op = _hestNextUnflagged(unflagVar+1, opt, numOpts); | |||
| 559 | np = opt[op].min; | |||
| 560 | sprintf(err, "%sdon't have %d parameter%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s for %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", _hestIdent(ident, opt+op, parm, 0)) | |||
| 561 | ME, np, np > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s for %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", _hestIdent(ident, opt+op, parm, 0)) | |||
| 562 | _hestIdent(ident, opt+op, parm, AIR_FALSE))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdon't have %d parameter%s for %s", ((parm && parm->verbosity) ? me : ""), np, np > 1 ? "s" : "", _hestIdent(ident, opt+op, parm, 0)); | |||
| 563 | return 1; | |||
| 564 | } | |||
| 565 | /* else we had enough args for all the unflagged options following | |||
| 566 | the sole variable parameter unflagged option, so snarf them up */ | |||
| 567 | for (op = _hestNextUnflagged(unflagVar+1, opt, numOpts); | |||
| 568 | op < numOpts; | |||
| 569 | op = _hestNextUnflagged(op+1, opt, numOpts)) { | |||
| 570 | np = opt[op].min; | |||
| 571 | prms[op] = _hestExtract(argcP, argv, nvp, np); | |||
| 572 | airMopAdd(pmop, prms[op], airFree, airMopAlways); | |||
| 573 | nprm[op] = np; | |||
| 574 | } | |||
| 575 | ||||
| 576 | /* now we grab the parameters of the sole variable parameter unflagged opt, | |||
| 577 | if it exists (unflagVar < numOpts) */ | |||
| 578 | if (unflagVar < numOpts) { | |||
| 579 | /* | |||
| 580 | printf("!%s: unflagVar=%d: min, nvp, max = %d %d %d\n", me, unflagVar, | |||
| 581 | opt[unflagVar].min, nvp, _hestMax(opt[unflagVar].max)); | |||
| 582 | */ | |||
| 583 | /* we'll do error checking for unexpected args later */ | |||
| 584 | nvp = AIR_MIN(nvp, _hestMax(opt[unflagVar].max))((nvp) < (_hestMax(opt[unflagVar].max)) ? (nvp) : (_hestMax (opt[unflagVar].max))); | |||
| 585 | if (nvp < (int)opt[unflagVar].min) { /* HEY scrutinize casts */ | |||
| 586 | sprintf(err, "%sdidn't get minimum of %d arg%s for %s (got %d)",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), opt[unflagVar ].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident , opt+unflagVar, parm, 1), nvp) | |||
| 587 | ME, opt[unflagVar].min,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), opt[unflagVar ].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident , opt+unflagVar, parm, 1), nvp) | |||
| 588 | opt[unflagVar].min > 1 ? "s" : "",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), opt[unflagVar ].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident , opt+unflagVar, parm, 1), nvp) | |||
| 589 | _hestIdent(ident, opt+unflagVar, parm, AIR_TRUE), nvp)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sdidn't get minimum of %d arg%s for %s (got %d)" , ((parm && parm->verbosity) ? me : ""), opt[unflagVar ].min, opt[unflagVar].min > 1 ? "s" : "", _hestIdent(ident , opt+unflagVar, parm, 1), nvp); | |||
| 590 | return 1; | |||
| 591 | } | |||
| 592 | if (nvp) { | |||
| 593 | prms[unflagVar] = _hestExtract(argcP, argv, 0, nvp); | |||
| 594 | airMopAdd(pmop, prms[unflagVar], airFree, airMopAlways); | |||
| 595 | nprm[unflagVar] = nvp; | |||
| 596 | } | |||
| 597 | else { | |||
| 598 | prms[unflagVar] = NULL((void*)0); | |||
| 599 | nprm[unflagVar] = 0; | |||
| 600 | } | |||
| 601 | } | |||
| 602 | return 0; | |||
| 603 | } | |||
| 604 | ||||
| 605 | int | |||
| 606 | _hestDefaults(char **prms, int *udflt, unsigned int *nprm, int *appr, | |||
| 607 | hestOpt *opt, | |||
| 608 | char *err, const hestParm *parm, airArray *mop) { | |||
| 609 | char *tmpS, me[]="_hestDefaults: ", ident[AIR_STRLEN_HUGE(1024+1)]; | |||
| 610 | int op, numOpts; | |||
| 611 | ||||
| 612 | numOpts = _hestNumOpts(opt); | |||
| 613 | for (op=0; op<numOpts; op++) { | |||
| 614 | if (parm->verbosity) | |||
| 615 | printf("%s op=%d/%d: \"%s\" --> kind=%d, nprm=%u, appr=%d\n", | |||
| 616 | me, op, numOpts-1, prms[op], opt[op].kind, | |||
| 617 | nprm[op], appr[op]); | |||
| 618 | switch(opt[op].kind) { | |||
| 619 | case 1: | |||
| 620 | /* -------- (no-parameter) boolean flags -------- */ | |||
| 621 | /* default is indeed always ignored for the sake of setting the | |||
| 622 | option's value, but udflt is used downstream to set | |||
| 623 | the option's source. The info came from the user if | |||
| 624 | the flag appears, otherwise it is from the default. */ | |||
| 625 | udflt[op] = !appr[op]; | |||
| 626 | break; | |||
| 627 | case 2: | |||
| 628 | case 3: | |||
| 629 | /* -------- one required parameter -------- */ | |||
| 630 | /* -------- multiple required parameters -------- */ | |||
| 631 | /* we'll used defaults if the flag didn't appear */ | |||
| 632 | udflt[op] = opt[op].flag && !appr[op]; | |||
| 633 | break; | |||
| 634 | case 4: | |||
| 635 | /* -------- optional single variables -------- */ | |||
| 636 | /* if the flag appeared (if there is a flag) but the paramter didn't, | |||
| 637 | we'll "invert" the default; if the flag didn't appear (or if there | |||
| 638 | isn't a flag) and the parameter also didn't appear, we'll use the | |||
| 639 | default. In either case, nprm[op] will be zero, and in both cases, | |||
| 640 | we need to use the default information. */ | |||
| 641 | udflt[op] = (0 == nprm[op]); | |||
| 642 | /* | |||
| 643 | fprintf(stderr, "%s nprm[%d] = %u --> udflt[%d] = %d\n", me, | |||
| 644 | op, nprm[op], op, udflt[op]); | |||
| 645 | */ | |||
| 646 | break; | |||
| 647 | case 5: | |||
| 648 | /* -------- multiple optional parameters -------- */ | |||
| 649 | /* we'll use the default if the flag didn't appear (if there is a | |||
| 650 | flag) Otherwise, if nprm[op] is zero, then the user is saying, | |||
| 651 | I want zero parameters */ | |||
| 652 | udflt[op] = opt[op].flag && !appr[op]; | |||
| 653 | break; | |||
| 654 | } | |||
| 655 | if (!udflt[op]) | |||
| 656 | continue; | |||
| 657 | prms[op] = airStrdup(opt[op].dflt); | |||
| 658 | /* fprintf(stderr, "%s: prms[%d] = |%s|\n", me, op, prms[op]); */ | |||
| 659 | if (prms[op]) { | |||
| 660 | airMopAdd(mop, prms[op], airFree, airMopAlways); | |||
| 661 | airOneLinify(prms[op]); | |||
| 662 | tmpS = airStrdup(prms[op]); | |||
| 663 | nprm[op] = airStrntok(tmpS, " "); | |||
| 664 | airFree(tmpS); | |||
| 665 | /* printf("!%s: nprm[%d] in default = %u\n", me, op, nprm[op]); */ | |||
| 666 | if ((int)opt[op].min < _hestMax(opt[op].max)) { /* HEY scrutinize casts */ | |||
| 667 | if (!( AIR_IN_CL((int)opt[op].min, (int)nprm[op], _hestMax(opt[op].max))(((int)opt[op].min) <= ((int)nprm[op]) && ((int)nprm [op]) <= (_hestMax(opt[op].max))) /* HEY scrutinize casts */ | |||
| 668 | || (airTypeString == opt[op].type | |||
| 669 | && parm->elideMultipleEmptyStringDefault) )) { | |||
| 670 | sprintf(err, "%s# parameters (in default) for %s is %d, "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, " "but need between %d and %d", ((parm && parm->verbosity ) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt [op].min, _hestMax(opt[op].max)) | |||
| 671 | "but need between %d and %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, " "but need between %d and %d", ((parm && parm->verbosity ) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt [op].min, _hestMax(opt[op].max)) | |||
| 672 | ME, _hestIdent(ident, opt+op, parm, AIR_TRUE), nprm[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, " "but need between %d and %d", ((parm && parm->verbosity ) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt [op].min, _hestMax(opt[op].max)) | |||
| 673 | opt[op].min, _hestMax(opt[op].max))__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%s# parameters (in default) for %s is %d, " "but need between %d and %d", ((parm && parm->verbosity ) ? me : ""), _hestIdent(ident, opt+op, parm, 1), nprm[op], opt [op].min, _hestMax(opt[op].max)); | |||
| 674 | return 1; | |||
| 675 | } | |||
| 676 | } | |||
| 677 | } | |||
| 678 | } | |||
| 679 | return 0; | |||
| 680 | } | |||
| 681 | ||||
| 682 | /* | |||
| 683 | ** this function moved from air/miscAir; the usage below | |||
| 684 | ** is its only usage in Teem | |||
| 685 | */ | |||
| 686 | static int | |||
| 687 | airIStore(void *v, int t, int i) { | |||
| 688 | ||||
| 689 | switch(t) { | |||
| 690 | case airTypeBool: return (*((int*)v) = !!i); break; | |||
| 691 | case airTypeInt: return (*((int*)v) = i); break; | |||
| 692 | case airTypeUInt: return (int)(*((unsigned int*)v) = i); break; | |||
| 693 | case airTypeLongInt:return (int)(*((long int*)v) = i); break; | |||
| 694 | case airTypeULongInt:return (int)(*((unsigned long int*)v) = i); break; | |||
| 695 | case airTypeSize_t: return (int)(*((size_t*)v) = i); break; | |||
| 696 | case airTypeFloat: return (int)(*((float*)v) = (float)(i)); break; | |||
| 697 | case airTypeDouble: return (int)(*((double*)v) = (double)(i)); break; | |||
| 698 | case airTypeChar: return (*((char*)v) = (char)(i)); break; | |||
| 699 | default: return 0; break; | |||
| 700 | } | |||
| 701 | } | |||
| 702 | ||||
| 703 | /* | |||
| 704 | ** this function moved from air/miscAir; the usage below | |||
| 705 | ** is its only usage in Teem | |||
| 706 | */ | |||
| 707 | double | |||
| 708 | airDLoad(void *v, int t) { | |||
| 709 | ||||
| 710 | switch(t) { | |||
| 711 | case airTypeBool: return AIR_CAST(double,*((int*)v))((double)(*((int*)v))); break; | |||
| 712 | case airTypeInt: return AIR_CAST(double,*((int*)v))((double)(*((int*)v))); break; | |||
| 713 | case airTypeUInt: return AIR_CAST(double,*((unsigned int*)v))((double)(*((unsigned int*)v))); break; | |||
| 714 | case airTypeLongInt:return AIR_CAST(double,*((long int*)v))((double)(*((long int*)v))); break; | |||
| 715 | case airTypeULongInt:return AIR_CAST(double,*((unsigned long int*)v))((double)(*((unsigned long int*)v))); break; | |||
| 716 | case airTypeSize_t: return AIR_CAST(double, *((size_t*)v))((double)(*((size_t*)v))); break; | |||
| 717 | case airTypeFloat: return AIR_CAST(double,*((float*)v))((double)(*((float*)v))); break; | |||
| 718 | case airTypeDouble: return *((double*)v); break; | |||
| 719 | case airTypeChar: return AIR_CAST(double,*((char*)v))((double)(*((char*)v))); break; | |||
| 720 | default: return 0; break; | |||
| 721 | } | |||
| 722 | } | |||
| 723 | ||||
| 724 | ||||
| 725 | int | |||
| 726 | _hestSetValues(char **prms, int *udflt, unsigned int *nprm, int *appr, | |||
| 727 | hestOpt *opt, | |||
| 728 | char *err, const hestParm *parm, airArray *pmop) { | |||
| 729 | char ident[AIR_STRLEN_HUGE(1024+1)], me[]="_hestSetValues: ", | |||
| 730 | cberr[AIR_STRLEN_HUGE(1024+1)], *tok, *last, *prmsCopy; | |||
| 731 | double tmpD; | |||
| 732 | int op, type, numOpts, p, ret; | |||
| 733 | void *vP; | |||
| 734 | char *cP; | |||
| 735 | size_t size; | |||
| 736 | ||||
| 737 | numOpts = _hestNumOpts(opt); | |||
| 738 | for (op=0; op<numOpts; op++) { | |||
| ||||
| 739 | _hestIdent(ident, opt+op, parm, AIR_TRUE1); | |||
| 740 | opt[op].source = udflt[op] ? hestSourceDefault : hestSourceUser; | |||
| 741 | type = opt[op].type; | |||
| 742 | size = (airTypeEnum == type | |||
| 743 | ? (int)sizeof(int) /* HEY scrutinize casts */ | |||
| 744 | : (airTypeOther == type | |||
| 745 | ? (int)opt[op].CB->size /* HEY scrutinize casts */ | |||
| 746 | : (int)airTypeSize[type])); /* HEY scrutinize casts */ | |||
| 747 | cP = (char *)(vP = opt[op].valueP); | |||
| 748 | if (parm->verbosity) { | |||
| 749 | printf("%s %d of %d: \"%s\": |%s| --> kind=%d, type=%d, size=%d\n", | |||
| 750 | me, op, numOpts-1, prms[op], ident, opt[op].kind, type, | |||
| 751 | (int)size); | |||
| 752 | } | |||
| 753 | /* we may over-write these */ | |||
| 754 | opt[op].alloc = 0; | |||
| 755 | if (opt[op].sawP) { | |||
| 756 | *(opt[op].sawP) = 0; | |||
| 757 | } | |||
| 758 | switch(opt[op].kind) { | |||
| 759 | case 1: | |||
| 760 | /* -------- parameter-less boolean flags -------- */ | |||
| 761 | if (vP) | |||
| 762 | *((int*)vP) = appr[op]; | |||
| 763 | break; | |||
| 764 | case 2: | |||
| 765 | /* -------- one required parameter -------- */ | |||
| 766 | if (prms[op] && vP) { | |||
| 767 | switch (type) { | |||
| 768 | case airTypeEnum: | |||
| 769 | if (1 != airParseStrE((int *)vP, prms[op], " ", 1, opt[op].enm)) { | |||
| 770 | sprintf(err, "%scouldn\'t parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn\'t parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].enm->name, ident) | |||
| 771 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn\'t parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].enm->name, ident) | |||
| 772 | opt[op].enm->name, ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn\'t parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].enm->name, ident); | |||
| 773 | return 1; | |||
| 774 | } | |||
| 775 | break; | |||
| 776 | case airTypeOther: | |||
| 777 | strcpy(cberr, "")__builtin___strcpy_chk (cberr, "", __builtin_object_size (cberr , 2 > 1 ? 1 : 0)); | |||
| 778 | ret = opt[op].CB->parse(vP, prms[op], cberr); | |||
| 779 | if (ret) { | |||
| 780 | if (strlen(cberr)) { | |||
| 781 | sprintf(err, "%serror parsing \"%s\" as %s for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s", ((parm && parm->verbosity) ? me : ""), prms[op], opt [op].CB->type, ident, cberr) | |||
| 782 | ME, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s", ((parm && parm->verbosity) ? me : ""), prms[op], opt [op].CB->type, ident, cberr); | |||
| 783 | } else { | |||
| 784 | sprintf(err, "%serror parsing \"%s\" as %s for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d" , ((parm && parm->verbosity) ? me : ""), prms[op], opt[op].CB->type, ident, ret) | |||
| 785 | ME, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d" , ((parm && parm->verbosity) ? me : ""), prms[op], opt[op].CB->type, ident, ret); | |||
| 786 | } | |||
| 787 | return ret; | |||
| 788 | } | |||
| 789 | if (opt[op].CB->destroy) { | |||
| 790 | /* vP is the address of a void*, we manage the void * */ | |||
| 791 | opt[op].alloc = 1; | |||
| 792 | airMopAdd(pmop, (void**)vP, (airMopper)airSetNull, airMopOnError); | |||
| 793 | airMopAdd(pmop, *((void**)vP), opt[op].CB->destroy, airMopOnError); | |||
| 794 | } | |||
| 795 | break; | |||
| 796 | case airTypeString: | |||
| 797 | if (1 != airParseStrS((char **)vP, prms[op], " ", 1, | |||
| 798 | parm->greedySingleString)) { | |||
| 799 | sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 800 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 801 | airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident); | |||
| 802 | return 1; | |||
| 803 | } | |||
| 804 | /* vP is the address of a char* (a char **), but what we | |||
| 805 | manage with airMop is the char * */ | |||
| 806 | opt[op].alloc = 1; | |||
| 807 | airMopMem(pmop, vP, airMopOnError); | |||
| 808 | break; | |||
| 809 | default: | |||
| 810 | /* type isn't string or enum, so no last arg to airParseStr[type] */ | |||
| 811 | if (1 != airParseStr[type](vP, prms[op], " ", 1)) { | |||
| 812 | sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 813 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 814 | airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident); | |||
| 815 | return 1; | |||
| 816 | } | |||
| 817 | break; | |||
| 818 | } | |||
| 819 | } | |||
| 820 | break; | |||
| 821 | case 3: | |||
| 822 | /* -------- multiple required parameters -------- */ | |||
| 823 | if (prms[op] && vP) { | |||
| 824 | switch (type) { | |||
| 825 | case airTypeEnum: | |||
| 826 | if (opt[op].min != /* min == max */ | |||
| 827 | airParseStrE((int *)vP, prms[op], " ", opt[op].min, opt[op].enm)) { | |||
| 828 | sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, opt[op].enm-> name, opt[op].min > 1 ? "s" : "", ident) | |||
| 829 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, opt[op].enm-> name, opt[op].min > 1 ? "s" : "", ident) | |||
| 830 | opt[op].min, opt[op].enm->name,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, opt[op].enm-> name, opt[op].min > 1 ? "s" : "", ident) | |||
| 831 | opt[op].min > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, opt[op].enm-> name, opt[op].min > 1 ? "s" : "", ident); | |||
| 832 | return 1; | |||
| 833 | } | |||
| 834 | break; | |||
| 835 | case airTypeOther: | |||
| 836 | prmsCopy = airStrdup(prms[op]); | |||
| 837 | for (p=0; p<(int)opt[op].min; p++) { /* HEY scrutinize casts */ | |||
| 838 | tok = airStrtok(!p ? prmsCopy : NULL((void*)0), " ", &last); | |||
| 839 | strcpy(cberr, "")__builtin___strcpy_chk (cberr, "", __builtin_object_size (cberr , 2 > 1 ? 1 : 0)); | |||
| 840 | ret = opt[op].CB->parse(cP + p*size, tok, cberr); | |||
| 841 | if (ret) { | |||
| 842 | if (strlen(cberr)) | |||
| 843 | sprintf(err, "%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s:\n%s", ((parm && parm->verbosity) ? me : "" ), tok, prms[op], opt[op].CB->type, ident, cberr) | |||
| 844 | "for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s:\n%s", ((parm && parm->verbosity) ? me : "" ), tok, prms[op], opt[op].CB->type, ident, cberr) | |||
| 845 | ME, tok, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s:\n%s", ((parm && parm->verbosity) ? me : "" ), tok, prms[op], opt[op].CB->type, ident, cberr); | |||
| 846 | else | |||
| 847 | sprintf(err, "%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s: returned %d", ((parm && parm->verbosity) ? me : ""), tok, prms[op], opt[op].CB->type, ident, ret) | |||
| 848 | "for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s: returned %d", ((parm && parm->verbosity) ? me : ""), tok, prms[op], opt[op].CB->type, ident, ret) | |||
| 849 | ME, tok, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s: returned %d", ((parm && parm->verbosity) ? me : ""), tok, prms[op], opt[op].CB->type, ident, ret); | |||
| 850 | free(prmsCopy); | |||
| 851 | return 1; | |||
| 852 | } | |||
| 853 | } | |||
| 854 | free(prmsCopy); | |||
| 855 | if (opt[op].CB->destroy) { | |||
| 856 | /* vP is an array of void*s, we manage the individual void*s */ | |||
| 857 | opt[op].alloc = 2; | |||
| 858 | for (p=0; p<(int)opt[op].min; p++) { /* HEY scrutinize casts */ | |||
| 859 | airMopAdd(pmop, ((void**)vP)+p, (airMopper)airSetNull, | |||
| 860 | airMopOnError); | |||
| 861 | airMopAdd(pmop, *(((void**)vP)+p), opt[op].CB->destroy, | |||
| 862 | airMopOnError); | |||
| 863 | } | |||
| 864 | } | |||
| 865 | break; | |||
| 866 | case airTypeString: | |||
| 867 | if (opt[op].min != /* min == max */ | |||
| 868 | airParseStr[type](vP, prms[op], " ", opt[op].min, AIR_FALSE0)) { | |||
| 869 | sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident) | |||
| 870 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident) | |||
| 871 | opt[op].min, airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident) | |||
| 872 | opt[op].min > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident); | |||
| 873 | return 1; | |||
| 874 | } | |||
| 875 | /* vP is an array of char*s, (a char**), and what we manage | |||
| 876 | with airMop are the individual vP[p]. */ | |||
| 877 | opt[op].alloc = 2; | |||
| 878 | for (p=0; p<(int)opt[op].min; p++) { /* HEY scrutinize casts */ | |||
| 879 | airMopMem(pmop, &(((char**)vP)[p]), airMopOnError); | |||
| 880 | } | |||
| 881 | break; | |||
| 882 | default: | |||
| 883 | if (opt[op].min != /* min == max */ | |||
| 884 | airParseStr[type](vP, prms[op], " ", opt[op].min)) { | |||
| 885 | sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident) | |||
| 886 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident) | |||
| 887 | opt[op].min, airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident) | |||
| 888 | opt[op].min > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].min, airTypeStr[type] , opt[op].min > 1 ? "s" : "", ident); | |||
| 889 | return 1; | |||
| 890 | } | |||
| 891 | break; | |||
| 892 | } | |||
| 893 | } | |||
| 894 | break; | |||
| 895 | case 4: | |||
| 896 | /* -------- optional single variables -------- */ | |||
| 897 | if (prms[op] && vP) { | |||
| 898 | switch (type) { | |||
| 899 | case airTypeEnum: | |||
| 900 | if (1 != airParseStrE((int *)vP, prms[op], " ", 1, opt[op].enm)) { | |||
| 901 | sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].enm->name, ident) | |||
| 902 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].enm->name, ident) | |||
| 903 | opt[op].enm->name, ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], opt[op].enm->name, ident); | |||
| 904 | return 1; | |||
| 905 | } | |||
| 906 | break; | |||
| 907 | case airTypeOther: | |||
| 908 | /* we're parsing an "other". We will not perform the special | |||
| 909 | flagged single variable parameter games as done above, so | |||
| 910 | whether this option is flagged or unflagged, we're going | |||
| 911 | to treat it like an unflagged single variable parameter option: | |||
| 912 | if the parameter didn't appear, we'll parse it from the default, | |||
| 913 | if it did appear, we'll parse it from the command line. Setting | |||
| 914 | up prms[op] thusly has already been done by _hestDefaults() */ | |||
| 915 | strcpy(cberr, "")__builtin___strcpy_chk (cberr, "", __builtin_object_size (cberr , 2 > 1 ? 1 : 0)); | |||
| 916 | ret = opt[op].CB->parse(vP, prms[op], cberr); | |||
| 917 | if (ret) { | |||
| 918 | if (strlen(cberr)) | |||
| 919 | sprintf(err, "%serror parsing \"%s\" as %s for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s", ((parm && parm->verbosity) ? me : ""), prms[op], opt [op].CB->type, ident, cberr) | |||
| 920 | ME, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s:\n%s", ((parm && parm->verbosity) ? me : ""), prms[op], opt [op].CB->type, ident, cberr); | |||
| 921 | else | |||
| 922 | sprintf(err, "%serror parsing \"%s\" as %s for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d" , ((parm && parm->verbosity) ? me : ""), prms[op], opt[op].CB->type, ident, ret) | |||
| 923 | ME, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" as %s for %s: returned %d" , ((parm && parm->verbosity) ? me : ""), prms[op], opt[op].CB->type, ident, ret); | |||
| 924 | return 1; | |||
| 925 | } | |||
| 926 | if (opt[op].CB->destroy) { | |||
| 927 | /* vP is the address of a void*, we manage the void* */ | |||
| 928 | opt[op].alloc = 1; | |||
| 929 | airMopAdd(pmop, vP, (airMopper)airSetNull, airMopOnError); | |||
| 930 | airMopAdd(pmop, *((void**)vP), opt[op].CB->destroy, airMopOnError); | |||
| 931 | } | |||
| 932 | break; | |||
| 933 | case airTypeString: | |||
| 934 | if (1 != airParseStr[type](vP, prms[op], " ", 1, | |||
| 935 | parm->greedySingleString)) { | |||
| 936 | sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 937 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 938 | airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident); | |||
| 939 | return 1; | |||
| 940 | } | |||
| 941 | opt[op].alloc = 1; | |||
| 942 | if (opt[op].flag && 1 == _hestCase(opt, udflt, nprm, appr, op)) { | |||
| 943 | /* we just parsed the default, but now we want to "invert" it */ | |||
| 944 | *((char**)vP) = (char *)airFree(*((char**)vP)); | |||
| 945 | opt[op].alloc = 0; | |||
| 946 | } | |||
| 947 | /* vP is the address of a char* (a char**), and what we | |||
| 948 | manage with airMop is the char * */ | |||
| 949 | airMopMem(pmop, vP, airMopOnError); | |||
| 950 | break; | |||
| 951 | default: | |||
| 952 | if (1 != airParseStr[type](vP, prms[op], " ", 1)) { | |||
| 953 | sprintf(err, "%scouldn't parse %s\"%s\" as %s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 954 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident) | |||
| 955 | airTypeStr[type], ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %s for %s", ( (parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], airTypeStr[type], ident); | |||
| 956 | return 1; | |||
| 957 | } | |||
| 958 | opt[op].alloc = 0; | |||
| 959 | if (1 == _hestCase(opt, udflt, nprm, appr, op)) { | |||
| 960 | /* we just parsed the default, but now we want to "invert" it */ | |||
| 961 | tmpD = airDLoad(vP, type); | |||
| 962 | airIStore(vP, type, tmpD ? 0 : 1); | |||
| 963 | } | |||
| 964 | break; | |||
| 965 | } | |||
| 966 | } | |||
| 967 | break; | |||
| 968 | case 5: | |||
| 969 | /* -------- multiple optional parameters -------- */ | |||
| 970 | /* hammerhead problems in this case; | |||
| 971 | may have been from calloc(0), fixed below */ | |||
| 972 | if (prms[op] && vP) { | |||
| 973 | if (1 == _hestCase(opt, udflt, nprm, appr, op)) { | |||
| 974 | *((void**)vP) = NULL((void*)0); | |||
| 975 | /* alloc and sawP set above */ | |||
| 976 | } else { | |||
| 977 | if (airTypeString == type) { | |||
| 978 | /* this is sneakiness: we allocate one more element so that | |||
| 979 | the resulting char** is, like argv, NULL-terminated */ | |||
| 980 | *((void**)vP) = calloc(nprm[op]+1, size); | |||
| 981 | } else { | |||
| 982 | if (nprm[op]) { | |||
| 983 | /* only allocate if there's something to allocate */ | |||
| 984 | *((void**)vP) = calloc(nprm[op], size); | |||
| 985 | } else { | |||
| 986 | *((void**)vP) = NULL((void*)0); | |||
| 987 | } | |||
| 988 | } | |||
| 989 | if (parm->verbosity) { | |||
| 990 | printf("!%s: nprm[%d] = %u\n", me, op, nprm[op]); | |||
| 991 | printf("!%s: new array (size %u*%u) is at 0x%p\n", me, | |||
| 992 | nprm[op], (unsigned int)size, *((void**)vP)); | |||
| 993 | } | |||
| 994 | if (*((void**)vP)) { | |||
| 995 | airMopMem(pmop, vP, airMopOnError); | |||
| 996 | } | |||
| 997 | *(opt[op].sawP) = nprm[op]; | |||
| 998 | /* so far everything we've done is regardless of type */ | |||
| 999 | switch (type) { | |||
| 1000 | case airTypeEnum: | |||
| 1001 | opt[op].alloc = 1; | |||
| 1002 | if (nprm[op] != | |||
| 1003 | airParseStrE((int *)(*((void**)vP)), prms[op], " ", nprm[op], | |||
| 1004 | opt[op].enm)) { | |||
| 1005 | sprintf(err, "%scouldn't parse %s\"%s\" as %u %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], opt[op].enm->name , nprm[op] > 1 ? "s" : "", ident) | |||
| 1006 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], opt[op].enm->name , nprm[op] > 1 ? "s" : "", ident) | |||
| 1007 | nprm[op], opt[op].enm->name,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], opt[op].enm->name , nprm[op] > 1 ? "s" : "", ident) | |||
| 1008 | nprm[op] > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %u %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], opt[op].enm->name , nprm[op] > 1 ? "s" : "", ident); | |||
| 1009 | return 1; | |||
| 1010 | } | |||
| 1011 | break; | |||
| 1012 | case airTypeOther: | |||
| 1013 | cP = (char *)(*((void**)vP)); | |||
| 1014 | prmsCopy = airStrdup(prms[op]); | |||
| 1015 | opt[op].alloc = (opt[op].CB->destroy ? 3 : 1); | |||
| 1016 | for (p=0; p<(int)nprm[op]; p++) { /* HEY scrutinize casts */ | |||
| 1017 | tok = airStrtok(!p ? prmsCopy : NULL((void*)0), " ", &last); | |||
| 1018 | /* hammerhead problems went away when this line | |||
| 1019 | was replaced by the following one: | |||
| 1020 | strcpy(cberr, ""); | |||
| 1021 | */ | |||
| 1022 | cberr[0] = 0; | |||
| 1023 | ret = opt[op].CB->parse(cP + p*size, tok, cberr); | |||
| 1024 | if (ret) { | |||
| 1025 | if (strlen(cberr)) | |||
| 1026 | sprintf(err,"%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s:\n%s", ((parm && parm->verbosity) ? me : "" ), tok, prms[op], opt[op].CB->type, ident, cberr) | |||
| 1027 | "for %s:\n%s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s:\n%s", ((parm && parm->verbosity) ? me : "" ), tok, prms[op], opt[op].CB->type, ident, cberr) | |||
| 1028 | ME, tok, prms[op], opt[op].CB->type, ident, cberr)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s:\n%s", ((parm && parm->verbosity) ? me : "" ), tok, prms[op], opt[op].CB->type, ident, cberr); | |||
| 1029 | ||||
| 1030 | else | |||
| 1031 | sprintf(err, "%serror parsing \"%s\" (in \"%s\") as %s "__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s: returned %d", ((parm && parm->verbosity) ? me : ""), tok, prms[op], opt[op].CB->type, ident, ret) | |||
| 1032 | "for %s: returned %d",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s: returned %d", ((parm && parm->verbosity) ? me : ""), tok, prms[op], opt[op].CB->type, ident, ret) | |||
| 1033 | ME, tok, prms[op], opt[op].CB->type, ident, ret)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%serror parsing \"%s\" (in \"%s\") as %s " "for %s: returned %d", ((parm && parm->verbosity) ? me : ""), tok, prms[op], opt[op].CB->type, ident, ret); | |||
| 1034 | free(prmsCopy); | |||
| 1035 | return 1; | |||
| 1036 | } | |||
| 1037 | } | |||
| 1038 | free(prmsCopy); | |||
| 1039 | if (opt[op].CB->destroy) { | |||
| 1040 | for (p=0; p<(int)nprm[op]; p++) { /* HEY scrutinize casts */ | |||
| 1041 | /* avert your eyes. vP is the address of an array of void*s. | |||
| 1042 | We manage the void*s */ | |||
| 1043 | airMopAdd(pmop, (*((void***)vP))+p, (airMopper)airSetNull, | |||
| 1044 | airMopOnError); | |||
| 1045 | airMopAdd(pmop, *((*((void***)vP))+p), opt[op].CB->destroy, | |||
| ||||
| 1046 | airMopOnError); | |||
| 1047 | } | |||
| 1048 | } | |||
| 1049 | break; | |||
| 1050 | case airTypeString: | |||
| 1051 | opt[op].alloc = 3; | |||
| 1052 | if (nprm[op] != | |||
| 1053 | airParseStrS((char **)(*((void**)vP)), prms[op], " ", nprm[op], | |||
| 1054 | parm->greedySingleString)) { | |||
| 1055 | sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident) | |||
| 1056 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident) | |||
| 1057 | nprm[op], airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident) | |||
| 1058 | nprm[op] > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident); | |||
| 1059 | return 1; | |||
| 1060 | } | |||
| 1061 | /* vP is the address of an array of char*s (a char ***), and | |||
| 1062 | what we manage with airMop is the individual (*vP)[p], | |||
| 1063 | as well as vP itself (above). */ | |||
| 1064 | for (p=0; p<(int)nprm[op]; p++) { /* HEY scrutinize casts */ | |||
| 1065 | airMopAdd(pmop, (*((char***)vP))[p], airFree, airMopOnError); | |||
| 1066 | } | |||
| 1067 | /* do the NULL-termination described above */ | |||
| 1068 | (*((char***)vP))[nprm[op]] = NULL((void*)0); | |||
| 1069 | break; | |||
| 1070 | default: | |||
| 1071 | opt[op].alloc = 1; | |||
| 1072 | if (nprm[op] != | |||
| 1073 | airParseStr[type](*((void**)vP), prms[op], " ", nprm[op])) { | |||
| 1074 | sprintf(err, "%scouldn't parse %s\"%s\" as %d %s%s for %s",__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident) | |||
| 1075 | ME, udflt[op] ? "(default) " : "", prms[op],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident) | |||
| 1076 | nprm[op], airTypeStr[type],__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident) | |||
| 1077 | nprm[op] > 1 ? "s" : "", ident)__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%scouldn't parse %s\"%s\" as %d %s%s for %s" , ((parm && parm->verbosity) ? me : ""), udflt[op] ? "(default) " : "", prms[op], nprm[op], airTypeStr[type], nprm [op] > 1 ? "s" : "", ident); | |||
| 1078 | return 1; | |||
| 1079 | } | |||
| 1080 | break; | |||
| 1081 | } | |||
| 1082 | } | |||
| 1083 | } | |||
| 1084 | break; | |||
| 1085 | } | |||
| 1086 | } | |||
| 1087 | return 0; | |||
| 1088 | } | |||
| 1089 | ||||
| 1090 | /* | |||
| 1091 | ******** hestParse() | |||
| 1092 | ** | |||
| 1093 | ** documentation? | |||
| 1094 | */ | |||
| 1095 | int | |||
| 1096 | hestParse(hestOpt *opt, int _argc, const char **_argv, | |||
| 1097 | char **_errP, const hestParm *_parm) { | |||
| 1098 | char me[]="hestParse: "; | |||
| 1099 | char *param, *param_copy; | |||
| 1100 | char **argv, **prms, *err; | |||
| 1101 | int a, argc, argr, *appr, *udflt, nrf, numOpts, big, ret, i; | |||
| 1102 | unsigned int *nprm; | |||
| 1103 | airArray *mop; | |||
| 1104 | hestParm *parm; | |||
| 1105 | size_t start_index, end_index; | |||
| 1106 | ||||
| 1107 | numOpts = _hestNumOpts(opt); | |||
| 1108 | ||||
| 1109 | /* -------- initialize the mop! */ | |||
| 1110 | mop = airMopNew(); | |||
| 1111 | ||||
| 1112 | /* -------- either copy given _parm, or allocate one */ | |||
| 1113 | if (_parm) { | |||
| 1114 | parm = NULL((void*)0); | |||
| 1115 | } | |||
| 1116 | else { | |||
| 1117 | parm = hestParmNew(); | |||
| 1118 | airMopAdd(mop, parm, (airMopper)hestParmFree, airMopAlways); | |||
| 1119 | } | |||
| 1120 | /* how to const-correctly use parm or _parm in an expression */ | |||
| 1121 | #define PARM (_parm ? _parm : parm) | |||
| 1122 | ||||
| 1123 | /* -------- allocate the err string. To determine its size with total | |||
| 1124 | ridiculous safety we have to find the biggest things which can appear | |||
| 1125 | in the string. */ | |||
| 1126 | big = _hestErrStrlen(opt, _argc, _argv); | |||
| 1127 | if (!( err = AIR_CALLOC(big, char)(char*)(calloc((big), sizeof(char))) )) { | |||
| 1128 | fprintf(stderr__stderrp, "%s PANIC: couldn't allocate error message " | |||
| 1129 | "buffer (size %d)\n", me, big); | |||
| 1130 | /* exit(1); */ | |||
| 1131 | } | |||
| 1132 | if (_errP) { | |||
| 1133 | /* if they care about the error string, than it is mopped only | |||
| 1134 | when there _wasn't_ an error */ | |||
| 1135 | *_errP = err; | |||
| 1136 | airMopAdd(mop, _errP, (airMopper)airSetNull, airMopOnOkay); | |||
| 1137 | airMopAdd(mop, err, airFree, airMopOnOkay); | |||
| 1138 | } | |||
| 1139 | else { | |||
| 1140 | /* otherwise, we're making the error string just for our own | |||
| 1141 | convenience, and we'll always clean it up on exit */ | |||
| 1142 | airMopAdd(mop, err, airFree, airMopAlways); | |||
| 1143 | } | |||
| 1144 | ||||
| 1145 | /* -------- check on validity of the hestOpt array */ | |||
| 1146 | if (_hestPanic(opt, err, PARM)) { | |||
| 1147 | airMopError(mop); return 1; | |||
| 1148 | } | |||
| 1149 | ||||
| 1150 | /* -------- Create all the local arrays used to save state during | |||
| 1151 | the processing of all the different options */ | |||
| 1152 | nprm = AIR_CALLOC(numOpts, unsigned int)(unsigned int*)(calloc((numOpts), sizeof(unsigned int))); | |||
| 1153 | airMopMem(mop, &nprm, airMopAlways); | |||
| 1154 | appr = AIR_CALLOC(numOpts, int)(int*)(calloc((numOpts), sizeof(int))); | |||
| 1155 | airMopMem(mop, &appr, airMopAlways); | |||
| 1156 | udflt = AIR_CALLOC(numOpts, int)(int*)(calloc((numOpts), sizeof(int))); | |||
| 1157 | airMopMem(mop, &udflt, airMopAlways); | |||
| 1158 | prms = AIR_CALLOC(numOpts, char *)(char **)(calloc((numOpts), sizeof(char *))); | |||
| 1159 | airMopMem(mop, &prms, airMopAlways); | |||
| 1160 | for (a=0; a<numOpts; a++) { | |||
| 1161 | prms[a] = NULL((void*)0); | |||
| 1162 | } | |||
| 1163 | ||||
| 1164 | /* -------- find out how big the argv array needs to be, first | |||
| 1165 | by seeing how many args are in the response files, and then adding | |||
| 1166 | on the args from the actual argv (getting this right the first time | |||
| 1167 | greatly simplifies the problem of eliminating memory leaks) */ | |||
| 1168 | if (_hestArgsInResponseFiles(&argr, &nrf, _argv, err, PARM)) { | |||
| 1169 | airMopError(mop); return 1; | |||
| 1170 | } | |||
| 1171 | argc = argr + _argc - nrf; | |||
| 1172 | ||||
| 1173 | if (PARM->verbosity) { | |||
| 1174 | printf("!%s: nrf = %d; argr = %d; _argc = %d --> argc = %d\n", | |||
| 1175 | me, nrf, argr, _argc, argc); | |||
| 1176 | } | |||
| 1177 | argv = AIR_CALLOC(argc+1, char *)(char **)(calloc((argc+1), sizeof(char *))); | |||
| 1178 | airMopMem(mop, &argv, airMopAlways); | |||
| 1179 | ||||
| 1180 | /* -------- process response files (if any) and set the remaining | |||
| 1181 | elements of argv */ | |||
| 1182 | if (PARM->verbosity) printf("%s: #### calling hestResponseFiles\n", me); | |||
| 1183 | if (_hestResponseFiles(argv, _argv, PARM, mop)) { | |||
| 1184 | airMopError(mop); return 1; | |||
| 1185 | } | |||
| 1186 | if (PARM->verbosity) printf("%s: #### hestResponseFiles done!\n", me); | |||
| 1187 | /* | |||
| 1188 | _hestPrintArgv(argc, argv); | |||
| 1189 | */ | |||
| 1190 | ||||
| 1191 | /* -------- extract flags and their associated parameters from argv */ | |||
| 1192 | if (PARM->verbosity) printf("%s: #### calling hestExtractFlagged\n", me); | |||
| 1193 | if (_hestExtractFlagged(prms, nprm, appr, | |||
| 1194 | &argc, argv, | |||
| 1195 | opt, | |||
| 1196 | err, PARM, mop)) { | |||
| 1197 | airMopError(mop); return 1; | |||
| 1198 | } | |||
| 1199 | if (PARM->verbosity) printf("%s: #### hestExtractFlagged done!\n", me); | |||
| 1200 | /* | |||
| 1201 | _hestPrintArgv(argc, argv); | |||
| 1202 | */ | |||
| 1203 | ||||
| 1204 | /* -------- extract args for unflagged options */ | |||
| 1205 | if (PARM->verbosity) printf("%s: #### calling hestExtractUnflagged\n", me); | |||
| 1206 | if (_hestExtractUnflagged(prms, nprm, | |||
| 1207 | &argc, argv, | |||
| 1208 | opt, | |||
| 1209 | err, PARM, mop)) { | |||
| 1210 | airMopError(mop); return 1; | |||
| 1211 | } | |||
| 1212 | if (PARM->verbosity) printf("%s: #### hestExtractUnflagged done!\n", me); | |||
| 1213 | ||||
| 1214 | /* currently, any left over arguments indicate error */ | |||
| 1215 | if (argc) { | |||
| 1216 | sprintf(err, "%sunexpected arg%s: \"%s\"", ME,__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm && parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)" : ""), argv[0]) | |||
| 1217 | ('-' == argv[0][0]__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm && parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)" : ""), argv[0]) | |||
| 1218 | ? " (or unrecognized flag)"__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm && parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)" : ""), argv[0]) | |||
| 1219 | : ""), argv[0])__builtin___sprintf_chk (err, 0, __builtin_object_size (err, 2 > 1 ? 1 : 0), "%sunexpected arg%s: \"%s\"", ((parm && parm->verbosity) ? me : ""), ('-' == argv[0][0] ? " (or unrecognized flag)" : ""), argv[0]); | |||
| 1220 | airMopError(mop); return 1; | |||
| 1221 | } | |||
| 1222 | ||||
| 1223 | /* -------- learn defaults */ | |||
| 1224 | if (PARM->verbosity) printf("%s: #### calling hestDefaults\n", me); | |||
| 1225 | if (_hestDefaults(prms, udflt, nprm, appr, | |||
| 1226 | opt, | |||
| 1227 | err, PARM, mop)) { | |||
| 1228 | airMopError(mop); return 1; | |||
| 1229 | } | |||
| 1230 | if (PARM->verbosity) printf("%s: #### hestDefaults done!\n", me); | |||
| 1231 | ||||
| 1232 | /* remove quotes from strings | |||
| 1233 | if greedy wasn't turned on for strings, then we have no hope | |||
| 1234 | of capturing filenames with spaces. */ | |||
| 1235 | if ( PARM->greedySingleString ) { | |||
| 1236 | for (i=0; i<numOpts; i++) { | |||
| 1237 | param = prms[i]; | |||
| 1238 | param_copy = NULL((void*)0); | |||
| 1239 | if (param && strstr(param, " ")) { | |||
| 1240 | start_index = 0; | |||
| 1241 | end_index = strlen(param)-1; | |||
| 1242 | if (param[start_index] == '\"') | |||
| 1243 | start_index++; | |||
| 1244 | if (param[end_index] == '\"') | |||
| 1245 | end_index--; | |||
| 1246 | param_copy = AIR_CALLOC(end_index-start_index+2, char)(char*)(calloc((end_index-start_index+2), sizeof(char))); | |||
| 1247 | strncpy(param_copy,¶m[start_index],end_index-start_index+1)__builtin___strncpy_chk (param_copy, ¶m[start_index], end_index-start_index+1, __builtin_object_size (param_copy, 2 > 1 ? 1 : 0)); | |||
| 1248 | param_copy[end_index-start_index+1] = '\0'; | |||
| 1249 | strcpy(param,param_copy)__builtin___strcpy_chk (param, param_copy, __builtin_object_size (param, 2 > 1 ? 1 : 0)); | |||
| 1250 | free(param_copy); | |||
| 1251 | } | |||
| 1252 | } | |||
| 1253 | } | |||
| 1254 | ||||
| 1255 | /* -------- now, the actual parsing of values */ | |||
| 1256 | /* hammerhead problems in _hestSetValues */ | |||
| 1257 | if (PARM->verbosity) printf("%s: #### calling hestSetValues\n", me); | |||
| 1258 | ret = _hestSetValues(prms, udflt, nprm, appr, | |||
| 1259 | opt, | |||
| 1260 | err, PARM, mop); | |||
| 1261 | if (ret) { | |||
| 1262 | airMopError(mop); return ret; | |||
| 1263 | } | |||
| 1264 | ||||
| 1265 | if (PARM->verbosity) printf("%s: #### hestSetValues done!\n", me); | |||
| 1266 | #undef PARM | |||
| 1267 | ||||
| 1268 | airMopOkay(mop); | |||
| 1269 | return 0; | |||
| 1270 | } | |||
| 1271 | ||||
| 1272 | /* | |||
| 1273 | ******** hestParseFree() | |||
| 1274 | ** | |||
| 1275 | ** free()s whatever was allocated by hestParse() | |||
| 1276 | ** | |||
| 1277 | ** returns NULL only to facilitate use with the airMop functions. | |||
| 1278 | ** You should probably just ignore this quirk. | |||
| 1279 | */ | |||
| 1280 | void * | |||
| 1281 | hestParseFree(hestOpt *opt) { | |||
| 1282 | int op, i, numOpts; | |||
| 1283 | unsigned int ui; | |||
| 1284 | void **vP; | |||
| 1285 | void ***vAP; | |||
| 1286 | char **str; | |||
| 1287 | char ***strP; | |||
| 1288 | ||||
| 1289 | numOpts = _hestNumOpts(opt); | |||
| 1290 | for (op=0; op<numOpts; op++) { | |||
| 1291 | /* | |||
| 1292 | printf("!hestParseFree: op = %d/%d -> kind = %d; type = %d; alloc = %d\n", | |||
| 1293 | op, numOpts-1, opt[op].kind, opt[op].type, opt[op].alloc); | |||
| 1294 | */ | |||
| 1295 | vP = (void **)opt[op].valueP; | |||
| 1296 | vAP = (void ***)opt[op].valueP; | |||
| 1297 | str = (char **)opt[op].valueP; | |||
| 1298 | strP = (char ***)opt[op].valueP; | |||
| 1299 | switch (opt[op].alloc) { | |||
| 1300 | case 0: | |||
| 1301 | /* nothing was allocated */ | |||
| 1302 | break; | |||
| 1303 | case 1: | |||
| 1304 | if (airTypeOther != opt[op].type) { | |||
| 1305 | *vP = airFree(*vP); | |||
| 1306 | } | |||
| 1307 | else { | |||
| 1308 | /* alloc is one either because we parsed one thing, and we have a | |||
| 1309 | destroy callback, or, because we parsed a dynamically-created array | |||
| 1310 | of things, and we don't have a destroy callback */ | |||
| 1311 | if (opt[op].CB->destroy) { | |||
| 1312 | *vP = opt[op].CB->destroy(*vP); | |||
| 1313 | } | |||
| 1314 | else { | |||
| 1315 | *vP = airFree(*vP); | |||
| 1316 | } | |||
| 1317 | } | |||
| 1318 | break; | |||
| 1319 | case 2: | |||
| 1320 | if (airTypeString == opt[op].type) { | |||
| 1321 | for (i=0; i<(int)opt[op].min; i++) { /* HEY scrutinize casts */ | |||
| 1322 | str[i] = (char *)airFree(str[i]); | |||
| 1323 | } | |||
| 1324 | } | |||
| 1325 | else { | |||
| 1326 | for (i=0; i<(int)opt[op].min; i++) { /* HEY scrutinize casts */ | |||
| 1327 | vP[i] = opt[op].CB->destroy(vP[i]); | |||
| 1328 | } | |||
| 1329 | } | |||
| 1330 | break; | |||
| 1331 | case 3: | |||
| 1332 | if (airTypeString == opt[op].type) { | |||
| 1333 | for (ui=0; ui<*(opt[op].sawP); ui++) { | |||
| 1334 | (*strP)[ui] = (char *)airFree((*strP)[ui]); | |||
| 1335 | } | |||
| 1336 | *strP = (char **)airFree(*strP); | |||
| 1337 | } | |||
| 1338 | else { | |||
| 1339 | for (ui=0; ui<*(opt[op].sawP); ui++) { | |||
| 1340 | (*vAP)[ui] = opt[op].CB->destroy((*vAP)[ui]); | |||
| 1341 | } | |||
| 1342 | *vAP = (void **)airFree(*vAP); | |||
| 1343 | } | |||
| 1344 | break; | |||
| 1345 | } | |||
| 1346 | } | |||
| 1347 | return NULL((void*)0); | |||
| 1348 | } | |||
| 1349 | ||||
| 1350 | /* | |||
| 1351 | ******** hestParseOrDie() | |||
| 1352 | ** | |||
| 1353 | ** dumb little function which encapsulate a common usage of hest: | |||
| 1354 | ** first, make sure hestOpt is valid with hestOptCheck(). Then, | |||
| 1355 | ** if argc is 0 (and !parm->noArgsIsNoProblem): maybe show | |||
| 1356 | ** info, usage, and glossary, all according to given flags, then exit(1) | |||
| 1357 | ** if parsing failed: show error message, and maybe usage and glossary, | |||
| 1358 | ** again according to boolean flags, then exit(1) | |||
| 1359 | ** if parsing succeeded: return | |||
| 1360 | */ | |||
| 1361 | void | |||
| 1362 | hestParseOrDie(hestOpt *opt, int argc, const char **argv, | |||
| 1363 | hestParm *parm, | |||
| 1364 | const char *me, const char *info, | |||
| 1365 | int doInfo, int doUsage, int doGlossary) { | |||
| 1366 | int E; | |||
| 1367 | int argcBad; | |||
| 1368 | char *errS; | |||
| 1369 | ||||
| 1370 | if (opt) { | |||
| 1371 | if (hestOptCheck(opt, &errS)) { | |||
| 1372 | fprintf(stderr__stderrp, "ERROR in hest usage:\n%s\n", errS); free(errS); | |||
| 1373 | exit(1); | |||
| 1374 | } | |||
| 1375 | E = 0; | |||
| 1376 | /* argc is good if its non-zero, or (else) being zero is ok */ | |||
| 1377 | argcBad = !(argc || (parm && parm->noArgsIsNoProblem)); | |||
| 1378 | if ( argcBad || | |||
| 1379 | (E = hestParse(opt, argc, argv, &errS, parm)) ) { | |||
| 1380 | if (E) { | |||
| 1381 | if (argv[0] && !strcmp(argv[0], "--version")) { | |||
| 1382 | /* print version info and bail */ | |||
| 1383 | char vbuff[AIR_STRLEN_LARGE(512+1)]; | |||
| 1384 | airTeemVersionSprint(vbuff); | |||
| 1385 | printf("%s\n", vbuff); | |||
| 1386 | hestParmFree(parm); | |||
| 1387 | hestOptFree(opt); | |||
| 1388 | exit(0); | |||
| 1389 | } else if (argv[0] && !strcmp(argv[0], "--help")) { | |||
| 1390 | /* actually, not an error, they were asking for help */ | |||
| 1391 | E = 0; | |||
| 1392 | } else { | |||
| 1393 | fprintf(stderr__stderrp, "ERROR: %s\n", errS); | |||
| 1394 | } | |||
| 1395 | free(errS); | |||
| 1396 | } | |||
| 1397 | if (!E) { | |||
| 1398 | /* no error, just !argc */ | |||
| 1399 | if (doInfo && info) hestInfo(stdout__stdoutp, me?me:"", info, parm); | |||
| 1400 | } | |||
| 1401 | if (doUsage) hestUsage(E ? stderr__stderrp : stdout__stdoutp, opt, me?me:"", parm); | |||
| 1402 | if (doGlossary) hestGlossary(E ? stderr__stderrp : stdout__stdoutp, opt, parm); | |||
| 1403 | hestParmFree(parm); | |||
| 1404 | hestOptFree(opt); | |||
| 1405 | exit(1); | |||
| 1406 | } | |||
| 1407 | } | |||
| 1408 | ||||
| 1409 | return; | |||
| 1410 | } |