Mercurial > hg > nnchat
comparison th_args.c @ 377:9ad157feb99a
Sync th-libs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 03 Oct 2011 00:04:33 +0300 |
parents | 69aed051f84d |
children | afbc3bfd3e03 |
comparison
equal
deleted
inserted
replaced
376:1617d0a0c58e | 377:9ad157feb99a |
---|---|
126 | 126 |
127 /* Check if option requires an argument | 127 /* Check if option requires an argument |
128 */ | 128 */ |
129 static BOOL th_args_check_arg(optarg_t *o, char *optArg) | 129 static BOOL th_args_check_arg(optarg_t *o, char *optArg) |
130 { | 130 { |
131 if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL) { | 131 if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ && optArg == NULL) |
132 if (o->optShort != 0 && o->optLong != NULL) { | 132 { |
133 if (o->optShort != 0 && o->optLong != NULL) | |
134 { | |
133 THERR("Option '-%c ARG' (--%s=ARG) requires an argument!\n", | 135 THERR("Option '-%c ARG' (--%s=ARG) requires an argument!\n", |
134 o->optShort, o->optLong); | 136 o->optShort, o->optLong); |
135 } else if (o->optShort != 0) { | 137 } |
138 else if (o->optShort != 0) | |
139 { | |
136 THERR("Option '-%c ARG' requires an argument!\n", o->optShort); | 140 THERR("Option '-%c ARG' requires an argument!\n", o->optShort); |
137 } else if (o->optLong != NULL) { | 141 } |
142 else if (o->optLong != NULL) | |
143 { | |
138 THERR("Option --%s=ARG requires an argument!\n", o->optLong); | 144 THERR("Option --%s=ARG requires an argument!\n", o->optLong); |
139 } | 145 } |
140 | 146 |
141 return FALSE; | 147 return FALSE; |
142 } else | 148 } |
149 else | |
143 return TRUE; | 150 return TRUE; |
144 | |
145 } | 151 } |
146 | 152 |
147 | 153 |
148 /* Handle short options | 154 /* Handle short options |
149 */ | 155 */ |
153 BOOL (*handleOpt)(int, char *, char *)) | 159 BOOL (*handleOpt)(int, char *, char *)) |
154 { | 160 { |
155 char *tmpArg = currArg, *optArg; | 161 char *tmpArg = currArg, *optArg; |
156 int optN; | 162 int optN; |
157 BOOL isFound; | 163 BOOL isFound; |
158 | 164 |
159 /* Short options can be combined: -a -b -c == -abc */ | 165 /* Short options can be combined: -a -b -c == -abc */ |
160 while (*tmpArg) { | 166 while (*tmpArg) |
161 | 167 { |
162 for (optN = 0, isFound = FALSE; (optN < optListN) && !isFound; optN++) | 168 for (optN = 0, isFound = FALSE; (optN < optListN) && !isFound; optN++) |
163 if (*tmpArg == optList[optN].optShort) { | 169 if (*tmpArg == optList[optN].optShort) |
164 /* Get possible option argument, if needed */ | 170 { |
165 if ((optList[optN].optFlags & OPT_ARGMASK) != 0 && (++(*newArgIndex) < argc)) | 171 /* Get possible option argument, if needed */ |
166 optArg = argv[*newArgIndex]; | 172 if ((optList[optN].optFlags & OPT_ARGMASK) != 0 |
167 else | 173 && (++(*newArgIndex) < argc)) |
168 optArg = NULL; | 174 optArg = argv[*newArgIndex]; |
169 | 175 else |
170 /* Check if option argument is required */ | 176 optArg = NULL; |
171 if (!th_args_check_arg(&optList[optN], optArg)) | 177 |
172 return FALSE; | 178 /* Check if option argument is required */ |
173 else { | 179 if (!th_args_check_arg(&optList[optN], optArg)) |
174 char tmpStr[2] = { 0, 0 }; | |
175 | |
176 /* Option was given succesfully, try to handle it */ | |
177 wasGiven[optN] = TRUE; | |
178 | |
179 tmpStr[0] = *tmpArg; | |
180 | |
181 if (!handleOpt(optList[optN].optID, optArg, tmpStr)) | |
182 return FALSE; | 180 return FALSE; |
183 } | 181 else |
184 | 182 { |
185 isFound = TRUE; | 183 char tmpStr[2] = { 0, 0 }; |
186 } | 184 |
187 | 185 /* Option was given succesfully, try to handle it */ |
188 if (!isFound) { | 186 wasGiven[optN] = TRUE; |
187 | |
188 tmpStr[0] = *tmpArg; | |
189 | |
190 if (!handleOpt(optList[optN].optID, optArg, tmpStr)) | |
191 return FALSE; | |
192 } | |
193 | |
194 isFound = TRUE; | |
195 } | |
196 | |
197 if (!isFound) | |
198 { | |
189 THERR("Unknown short option '%c' in argument '-%s'\n", | 199 THERR("Unknown short option '%c' in argument '-%s'\n", |
190 *tmpArg, currArg); | 200 *tmpArg, currArg); |
191 return FALSE; | 201 return FALSE; |
192 } | 202 } |
193 | 203 |
194 tmpArg++; | 204 tmpArg++; |
195 } | 205 } |
205 optarg_t optList[], int optListN, | 215 optarg_t optList[], int optListN, |
206 BOOL (*handleOpt)(int, char *, char *)) | 216 BOOL (*handleOpt)(int, char *, char *)) |
207 { | 217 { |
208 int optN, optLen, i; | 218 int optN, optLen, i; |
209 char *optArg; | 219 char *optArg; |
210 | 220 |
211 (void) argc; (void) argv; (void) newArgIndex; | 221 (void) argc; |
212 | 222 (void) argv; |
223 (void) newArgIndex; | |
224 | |
213 /* Long option */ | 225 /* Long option */ |
214 for (optN = -1, optLen = i = 0; (i < optListN) && (optN < 0); i++) | 226 for (optN = -1, optLen = i = 0; (i < optListN) && (optN < 0); i++) |
215 if (optList[i].optLong) { | 227 if (optList[i].optLong) |
216 optLen = strlen(optList[i].optLong); | 228 { |
217 if (strncmp(currArg, optList[i].optLong, optLen) == 0) | 229 optLen = strlen(optList[i].optLong); |
218 optN = i; | 230 if (strncmp(currArg, optList[i].optLong, optLen) == 0) |
219 } | 231 optN = i; |
220 | 232 } |
233 | |
221 /* Get possible option argument, if needed */ | 234 /* Get possible option argument, if needed */ |
222 if (optN >= 0) { | 235 if (optN >= 0) |
223 if ((optList[optN].optFlags & OPT_ARGMASK) != 0) { | 236 { |
237 if ((optList[optN].optFlags & OPT_ARGMASK) != 0) | |
238 { | |
224 if (currArg[optLen] == '=') | 239 if (currArg[optLen] == '=') |
225 optArg = &currArg[optLen + 1]; | 240 optArg = &currArg[optLen + 1]; |
226 else | 241 else |
227 optArg = NULL; | 242 optArg = NULL; |
228 } else | 243 } |
244 else | |
229 optArg = NULL; | 245 optArg = NULL; |
230 | 246 |
231 /* Check if option argument is required */ | 247 /* Check if option argument is required */ |
232 if (!th_args_check_arg(&optList[optN], optArg)) | 248 if (!th_args_check_arg(&optList[optN], optArg)) |
233 return FALSE; | 249 return FALSE; |
234 else { | 250 else |
251 { | |
235 /* Option was given succesfully, try to handle it */ | 252 /* Option was given succesfully, try to handle it */ |
236 wasGiven[optN] = TRUE; | 253 wasGiven[optN] = TRUE; |
237 if (!handleOpt(optList[optN].optID, optArg, currArg)) | 254 if (!handleOpt(optList[optN].optID, optArg, currArg)) |
238 return FALSE; | 255 return FALSE; |
239 } | 256 } |
240 } else { | 257 } |
258 else | |
259 { | |
241 THERR("Unknown long option '--%s'\n", currArg); | 260 THERR("Unknown long option '--%s'\n", currArg); |
242 return FALSE; | 261 return FALSE; |
243 } | 262 } |
244 | 263 |
245 return TRUE; | 264 return TRUE; |
248 | 267 |
249 /* Process arguments, handling short and long options by | 268 /* Process arguments, handling short and long options by |
250 * calling the given callback functions. | 269 * calling the given callback functions. |
251 */ | 270 */ |
252 BOOL th_args_process(int argc, char *argv[], | 271 BOOL th_args_process(int argc, char *argv[], |
253 optarg_t optList[], int optListN, | 272 optarg_t optList[], int optListN, |
254 BOOL (*handleOpt) (int, char *, char *), | 273 BOOL(*handleOpt) (int, char *, char *), |
255 BOOL (*handleNonOption) (char *), BOOL bailOut) | 274 BOOL(*handleNonOption) (char *), BOOL bailOut) |
256 { | 275 { |
257 BOOL endOptions, optionsOK; | 276 BOOL endOptions, optionsOK; |
258 int argIndex, newArgIndex, i; | 277 int argIndex, newArgIndex, i; |
259 char *currArg; | 278 char *currArg; |
260 BOOL *wasGiven; | 279 BOOL *wasGiven; |
261 | 280 |
262 /* Allocate wasGiven */ | 281 /* Allocate wasGiven */ |
263 wasGiven = (BOOL *) th_calloc(optListN, sizeof(BOOL)); | 282 wasGiven = (BOOL *) th_calloc(optListN, sizeof(BOOL)); |
264 if (!wasGiven) { | 283 if (!wasGiven) |
265 THERR("FATAL ERROR! Could not allocate wasGiven in th_args_process()!\n"); | 284 { |
285 THERR | |
286 ("FATAL ERROR! Could not allocate wasGiven in th_args_process()!\n"); | |
266 exit(128); | 287 exit(128); |
267 } | 288 } |
268 | 289 |
269 /* Parse arguments */ | 290 /* Parse arguments */ |
270 argIndex = 1; | 291 argIndex = 1; |
271 optionsOK = TRUE; | 292 optionsOK = TRUE; |
272 endOptions = FALSE; | 293 endOptions = FALSE; |
273 while (argIndex < argc) { | 294 while (argIndex < argc) |
295 { | |
274 currArg = argv[argIndex]; | 296 currArg = argv[argIndex]; |
275 if ((currArg[0] == '-') && !endOptions) { | 297 if ((currArg[0] == '-') && !endOptions) |
298 { | |
276 newArgIndex = argIndex; | 299 newArgIndex = argIndex; |
277 currArg++; | 300 currArg++; |
278 if (*currArg == '-') { | 301 if (*currArg == '-') |
302 { | |
279 /* Check for "--", which ends the options-list */ | 303 /* Check for "--", which ends the options-list */ |
280 currArg++; | 304 currArg++; |
281 if (*currArg == 0) { | 305 if (*currArg == 0) |
306 { | |
282 endOptions = TRUE; | 307 endOptions = TRUE; |
283 continue; | 308 continue; |
284 } | 309 } |
285 | 310 |
286 /* Long options */ | 311 /* Long options */ |
287 if (!th_args_process_long(currArg, &newArgIndex, | 312 if (!th_args_process_long(currArg, &newArgIndex, |
288 wasGiven, argc, argv, optList, optListN, | 313 wasGiven, argc, argv, optList, |
289 handleOpt)) | 314 optListN, handleOpt)) |
290 optionsOK = FALSE; | 315 optionsOK = FALSE; |
291 } else { | 316 } |
317 else | |
318 { | |
292 /* Short options */ | 319 /* Short options */ |
293 if (!th_args_process_short(currArg, &newArgIndex, | 320 if (!th_args_process_short(currArg, &newArgIndex, |
294 wasGiven, argc, argv, optList, optListN, | 321 wasGiven, argc, argv, optList, |
295 handleOpt)) | 322 optListN, handleOpt)) |
296 optionsOK = FALSE; | 323 optionsOK = FALSE; |
297 } | 324 } |
298 | 325 |
299 argIndex = newArgIndex; | 326 argIndex = newArgIndex; |
300 } else { | 327 } |
328 else | |
329 { | |
301 /* Was not option argument */ | 330 /* Was not option argument */ |
302 if (handleNonOption == NULL || (handleNonOption != NULL && !handleNonOption(currArg))) { | 331 if (handleNonOption == NULL |
332 || (handleNonOption != NULL && !handleNonOption(currArg))) | |
333 { | |
303 THERR("Invalid argument '%s'\n", currArg); | 334 THERR("Invalid argument '%s'\n", currArg); |
304 optionsOK = FALSE; | 335 optionsOK = FALSE; |
305 } | 336 } |
306 } | 337 } |
307 | 338 |
308 /* Check if we bail out on invalid argument */ | 339 /* Check if we bail out on invalid argument */ |
309 if (!optionsOK && bailOut) { | 340 if (!optionsOK && bailOut) |
341 { | |
310 th_free(wasGiven); | 342 th_free(wasGiven); |
311 return FALSE; | 343 return FALSE; |
312 } | 344 } |
313 | 345 |
314 argIndex++; | 346 argIndex++; |
315 } | 347 } |
316 | 348 |
317 /* Check wasGiven by isRequired */ | 349 /* Check wasGiven by isRequired */ |
318 for (i = 0; i < optListN; i++) | 350 for (i = 0; i < optListN; i++) |
319 if ((optList[i].optFlags & OPT_REQUIRED) != 0 && !wasGiven[i]) { | 351 if ((optList[i].optFlags & OPT_REQUIRED) != 0 && !wasGiven[i]) |
320 THERR("Option -%s (--%s) is required.\n", | 352 { |
321 optList[i].optShort, optList[i].optLong); | 353 THERR("Option -%s (--%s) is required.\n", |
322 | 354 optList[i].optShort, optList[i].optLong); |
323 optionsOK = FALSE; | 355 |
324 if (bailOut) break; | 356 optionsOK = FALSE; |
325 } | 357 if (bailOut) |
326 | 358 break; |
359 } | |
360 | |
327 th_free(wasGiven); | 361 th_free(wasGiven); |
328 return optionsOK; | 362 return optionsOK; |
329 } | 363 } |
330 | 364 |
331 | 365 |
332 /* Print help for commandline arguments/options | 366 /* Print help for commandline arguments/options |
333 */ | 367 */ |
334 void th_args_help(FILE * outFile, | 368 void th_args_help(FILE * outFile, |
335 optarg_t optList[], int optListN, | 369 optarg_t optList[], int optListN, |
336 char * progName, char * progUsage) | 370 char *progName, char *progUsage) |
337 { | 371 { |
338 int i, nrequired; | 372 int i, nrequired; |
339 | 373 |
340 fprintf(outFile, | 374 fprintf(outFile, |
341 "\n%s v%s (%s)\n" | 375 "\n%s v%s (%s)\n" |
342 "%s\n" | 376 "%s\n" |
343 "%s\n" | 377 "%s\n" |
344 "Usage: %s %s\n", | 378 "Usage: %s %s\n", |
345 th_prog_name, th_prog_version, th_prog_fullname, | 379 th_prog_name, th_prog_version, th_prog_fullname, |
346 th_prog_author, th_prog_license, progName, progUsage); | 380 th_prog_author, th_prog_license, progName, progUsage); |
347 | 381 |
348 | 382 |
349 for (i = nrequired = 0; i < optListN; i++) { | 383 for (i = nrequired = 0; i < optListN; i++) |
384 { | |
350 optarg_t *o = &optList[i]; | 385 optarg_t *o = &optList[i]; |
351 | 386 |
352 /* Print short option */ | 387 /* Print short option */ |
353 if (o->optShort != 0) | 388 if (o->optShort != 0) |
354 fprintf(outFile, " -%c, ", o->optShort); | 389 fprintf(outFile, " -%c, ", o->optShort); |
355 else | 390 else |
356 fprintf(outFile, " "); | 391 fprintf(outFile, " "); |
357 | 392 |
358 /* Print long option */ | 393 /* Print long option */ |
359 if (o->optLong) { | 394 if (o->optLong) |
395 { | |
360 char tmpStr[64], *p; | 396 char tmpStr[64], *p; |
361 | 397 |
362 if ((o->optFlags & OPT_ARGMASK) == OPT_ARGOPT) { | 398 if ((o->optFlags & OPT_ARGMASK) == OPT_ARGOPT) |
363 snprintf(tmpStr, sizeof(tmpStr), "%s[=ARG]", optList[i].optLong); | 399 { |
400 snprintf(tmpStr, sizeof(tmpStr), "%s[=ARG]", | |
401 optList[i].optLong); | |
364 p = tmpStr; | 402 p = tmpStr; |
365 } else if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ) { | 403 } |
366 snprintf(tmpStr, sizeof(tmpStr), "%s=ARG", optList[i].optLong); | 404 else if ((o->optFlags & OPT_ARGMASK) == OPT_ARGREQ) |
405 { | |
406 snprintf(tmpStr, sizeof(tmpStr), "%s=ARG", | |
407 optList[i].optLong); | |
367 p = tmpStr; | 408 p = tmpStr; |
368 } else | 409 } |
410 else | |
369 p = o->optLong; | 411 p = o->optLong; |
370 | 412 |
371 fprintf(outFile, "--%-15s", p); | 413 fprintf(outFile, "--%-15s", p); |
372 } else | 414 } |
415 else | |
373 fprintf(outFile, " "); | 416 fprintf(outFile, " "); |
374 | 417 |
375 fprintf(outFile, " %s.", optList[i].optDesc); | 418 fprintf(outFile, " %s.", optList[i].optDesc); |
376 | 419 |
377 if (o->optFlags & OPT_REQUIRED) { | 420 if (o->optFlags & OPT_REQUIRED) |
421 { | |
378 fprintf(outFile, " [*]\n"); | 422 fprintf(outFile, " [*]\n"); |
379 nrequired++; | 423 nrequired++; |
380 } else | 424 } |
425 else | |
381 fprintf(outFile, "\n"); | 426 fprintf(outFile, "\n"); |
382 } | 427 } |
383 | 428 |
384 if (nrequired > 0) | 429 if (nrequired > 0) |
385 fprintf(outFile, "(Options marked with [*] are required)\n"); | 430 fprintf(outFile, "(Options marked with [*] are required)\n"); |
386 } | 431 } |
387 |