1 /** 2 * @file check.c 3 * 4 * @brief Hunt for options in the option descriptor list 5 * 6 * This file contains the routines that deal with processing quoted strings 7 * into an internal format. 8 * 9 * @addtogroup autoopts 10 * @{ 11 */ 12 /* 13 * This file is part of AutoOpts, a companion to AutoGen. 14 * AutoOpts is free software. 15 * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved 16 * 17 * AutoOpts is available under any one of two licenses. The license 18 * in use must be one of these two and the choice is under the control 19 * of the user of the license. 20 * 21 * The GNU Lesser General Public License, version 3 or later 22 * See the files "COPYING.lgplv3" and "COPYING.gplv3" 23 * 24 * The Modified Berkeley Software Distribution License 25 * See the file "COPYING.mbsd" 26 * 27 * These files have the following sha256 sums: 28 * 29 * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 30 * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 31 * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd 32 */ 33 34 /* = = = START-STATIC-FORWARD = = = */ 35 static int 36 parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz); 37 38 static void 39 opt_ambiguities(tOptions * opts, char const * name, int nm_len); 40 41 static int 42 opt_match_ct(tOptions * opts, char const * name, int nm_len, 43 int * ixp, bool * disable); 44 45 static tSuccess 46 opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st); 47 48 static tSuccess 49 opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st); 50 51 static tSuccess 52 opt_ambiguous(tOptions * opts, char const * name, int match_ct); 53 54 static tSuccess 55 get_opt_arg_must(tOptions * opts, tOptState * o_st); 56 57 static tSuccess 58 get_opt_arg_may(tOptions * pOpts, tOptState * o_st); 59 60 static tSuccess 61 get_opt_arg_none(tOptions * pOpts, tOptState * o_st); 62 /* = = = END-STATIC-FORWARD = = = */ 63 64 /** 65 * find the name and name length we are looking for 66 */ 67 static int 68 parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz) 69 { 70 int res = 0; 71 char const * p = *nm_pp; 72 *arg_pp = NULL; 73 74 for (;;) { 75 switch (*(p++)) { 76 case NUL: return res; 77 78 case '=': 79 memcpy(buf, *nm_pp, (size_t)res); 80 81 buf[res] = NUL; 82 *nm_pp = buf; 83 *arg_pp = VOIDP(p); 84 return res; 85 86 default: 87 if (++res >= (int)bufsz) 88 return -1; 89 } 90 } 91 } 92 93 /** 94 * print out the options that match the given name. 95 * 96 * @param pOpts option data 97 * @param opt_name name of option to look for 98 */ 99 static void 100 opt_ambiguities(tOptions * opts, char const * name, int nm_len) 101 { 102 char const * const hyph = 103 NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER; 104 105 tOptDesc * pOD = opts->pOptDesc; 106 int idx = 0; 107 108 fputs(zambig_list_msg, stderr); 109 do { 110 if (pOD->pz_Name == NULL) 111 continue; /* doc option */ 112 113 if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) 114 fprintf(stderr, zambig_file, hyph, pOD->pz_Name); 115 116 else if ( (pOD->pz_DisableName != NULL) 117 && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) 118 ) 119 fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName); 120 } while (pOD++, (++idx < opts->optCt)); 121 } 122 123 /** 124 * Determine the number of options that match the name 125 * 126 * @param pOpts option data 127 * @param opt_name name of option to look for 128 * @param nm_len length of provided name 129 * @param index pointer to int for option index 130 * @param disable pointer to bool to mark disabled option 131 * @return count of options that match 132 */ 133 static int 134 opt_match_ct(tOptions * opts, char const * name, int nm_len, 135 int * ixp, bool * disable) 136 { 137 int matchCt = 0; 138 int idx = 0; 139 int idxLim = opts->optCt; 140 tOptDesc * pOD = opts->pOptDesc; 141 142 do { 143 /* 144 * If option disabled or a doc option, skip to next 145 */ 146 if (pOD->pz_Name == NULL) 147 continue; 148 149 if ( SKIP_OPT(pOD) 150 && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT))) 151 continue; 152 153 if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) { 154 /* 155 * IF we have a complete match 156 * THEN it takes priority over any already located partial 157 */ 158 if (pOD->pz_Name[ nm_len ] == NUL) { 159 *ixp = idx; 160 return 1; 161 } 162 } 163 164 /* 165 * IF there is a disable name 166 * *AND* the option name matches the disable name 167 * THEN ... 168 */ 169 else if ( (pOD->pz_DisableName != NULL) 170 && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) 171 ) { 172 *disable = true; 173 174 /* 175 * IF we have a complete match 176 * THEN it takes priority over any already located partial 177 */ 178 if (pOD->pz_DisableName[ nm_len ] == NUL) { 179 *ixp = idx; 180 return 1; 181 } 182 } 183 184 else 185 continue; /* does not match any option */ 186 187 /* 188 * We found a full or partial match, either regular or disabling. 189 * Remember the index for later. 190 */ 191 *ixp = idx; 192 ++matchCt; 193 194 } while (pOD++, (++idx < idxLim)); 195 196 return matchCt; 197 } 198 199 /** 200 * Set the option to the indicated option number. 201 * 202 * @param opts option data 203 * @param arg option argument (if glued to name) 204 * @param idx option index 205 * @param disable mark disabled option 206 * @param st state about current option 207 */ 208 static tSuccess 209 opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st) 210 { 211 tOptDesc * pOD = opts->pOptDesc + idx; 212 213 if (SKIP_OPT(pOD)) { 214 if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) 215 return FAILURE; 216 217 fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name); 218 if (pOD->pzText != NULL) 219 fprintf(stderr, SET_OFF_FMT, pOD->pzText); 220 fputc(NL, stderr); 221 (*opts->pUsageProc)(opts, EXIT_FAILURE); 222 /* NOTREACHED */ 223 _exit(EXIT_FAILURE); /* to be certain */ 224 } 225 226 /* 227 * IF we found a disablement name, 228 * THEN set the bit in the callers' flag word 229 */ 230 if (disable) 231 st->flags |= OPTST_DISABLED; 232 233 st->pOD = pOD; 234 st->pzOptArg = arg; 235 st->optType = TOPT_LONG; 236 237 return SUCCESS; 238 } 239 240 /** 241 * An option was not found. Check for default option and set it 242 * if there is one. Otherwise, handle the error. 243 * 244 * @param opts option data 245 * @param name name of option to look for 246 * @param arg option argument 247 * @param st state about current option 248 * 249 * @return success status 250 */ 251 static tSuccess 252 opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st) 253 { 254 /* 255 * IF there is no equal sign 256 * *AND* we are using named arguments 257 * *AND* there is a default named option, 258 * THEN return that option. 259 */ 260 if ( (arg == NULL) 261 && NAMED_OPTS(opts) 262 && (opts->specOptIdx.default_opt != NO_EQUIVALENT)) { 263 264 st->pOD = opts->pOptDesc + opts->specOptIdx.default_opt; 265 st->pzOptArg = name; 266 st->optType = TOPT_DEFAULT; 267 return SUCCESS; 268 } 269 270 if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { 271 fprintf(stderr, zIllOptStr, opts->pzProgPath, name); 272 (*opts->pUsageProc)(opts, EXIT_FAILURE); 273 /* NOTREACHED */ 274 _exit(EXIT_FAILURE); /* to be certain */ 275 } 276 277 return FAILURE; 278 } 279 280 /** 281 * Several options match the provided name. 282 * 283 * @param opts option data 284 * @param name name of option to look for 285 * @param match_ct number of matching options 286 * 287 * @return success status (always FAILURE, if it returns) 288 */ 289 static tSuccess 290 opt_ambiguous(tOptions * opts, char const * name, int match_ct) 291 { 292 if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { 293 fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct); 294 if (match_ct <= 4) 295 opt_ambiguities(opts, name, (int)strlen(name)); 296 (*opts->pUsageProc)(opts, EXIT_FAILURE); 297 /* NOTREACHED */ 298 _exit(EXIT_FAILURE); /* to be certain */ 299 } 300 return FAILURE; 301 } 302 303 /*=export_func optionVendorOption 304 * private: 305 * 306 * what: Process a vendor option 307 * arg: + tOptions * + pOpts + program options descriptor + 308 * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + 309 * 310 * doc: 311 * For POSIX specified utilities, the options are constrained to the options, 312 * @xref{config attributes, Program Configuration}. AutoOpts clients should 313 * never specify this directly. It gets referenced when the option 314 * definitions contain a "vendor-opt" attribute. 315 =*/ 316 void 317 optionVendorOption(tOptions * pOpts, tOptDesc * pOD) 318 { 319 tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); 320 char const * vopt_str = pOD->optArg.argString; 321 322 if (pOpts <= OPTPROC_EMIT_LIMIT) 323 return; 324 325 if ((pOD->fOptState & OPTST_RESET) != 0) 326 return; 327 328 if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0) 329 opt_st.flags = OPTST_DEFINED; 330 331 if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0) 332 || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st)) 333 || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) ) 334 { 335 fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str); 336 (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); 337 /* NOTREACHED */ 338 _exit(EXIT_FAILURE); /* to be certain */ 339 } 340 341 /* 342 * See if we are in immediate handling state. 343 */ 344 if (pOpts->fOptSet & OPTPROC_IMMEDIATE) { 345 /* 346 * See if the enclosed option is okay with that state. 347 */ 348 if (DO_IMMEDIATELY(opt_st.flags)) 349 (void)handle_opt(pOpts, &opt_st); 350 351 } else { 352 /* 353 * non-immediate direction. 354 * See if the enclosed option is okay with that state. 355 */ 356 if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags)) 357 (void)handle_opt(pOpts, &opt_st); 358 } 359 } 360 361 /** 362 * Find the option descriptor by full name. 363 * 364 * @param opts option data 365 * @param opt_name name of option to look for 366 * @param state state about current option 367 * 368 * @return success status 369 */ 370 LOCAL tSuccess 371 opt_find_long(tOptions * opts, char const * opt_name, tOptState * state) 372 { 373 char name_buf[128]; 374 char * opt_arg; 375 int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf)); 376 377 int idx = 0; 378 bool disable = false; 379 int ct; 380 381 if (nm_len <= 1) { 382 if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) 383 return FAILURE; 384 385 fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name); 386 (*opts->pUsageProc)(opts, EXIT_FAILURE); 387 /* NOTREACHED */ 388 _exit(EXIT_FAILURE); /* to be certain */ 389 } 390 391 ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable); 392 393 /* 394 * See if we found one match, no matches or multiple matches. 395 */ 396 switch (ct) { 397 case 1: return opt_set(opts, opt_arg, idx, disable, state); 398 case 0: return opt_unknown(opts, opt_name, opt_arg, state); 399 default: return opt_ambiguous(opts, opt_name, ct); 400 } 401 } 402 403 404 /** 405 * Find the short option descriptor for the current option 406 * 407 * @param pOpts option data 408 * @param optValue option flag character 409 * @param pOptState state about current option 410 */ 411 LOCAL tSuccess 412 opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState) 413 { 414 tOptDesc * pRes = pOpts->pOptDesc; 415 int ct = pOpts->optCt; 416 417 /* 418 * Search the option list 419 */ 420 do { 421 if (optValue != pRes->optValue) 422 continue; 423 424 if (SKIP_OPT(pRes)) { 425 if ( (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) 426 && (pRes->pz_Name != NULL)) { 427 if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) 428 return FAILURE; 429 430 fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name); 431 if (pRes->pzText != NULL) 432 fprintf(stderr, SET_OFF_FMT, pRes->pzText); 433 fputc(NL, stderr); 434 (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); 435 /* NOTREACHED */ 436 _exit(EXIT_FAILURE); /* to be certain */ 437 } 438 goto short_opt_error; 439 } 440 441 pOptState->pOD = pRes; 442 pOptState->optType = TOPT_SHORT; 443 return SUCCESS; 444 445 } while (pRes++, --ct > 0); 446 447 /* 448 * IF the character value is a digit 449 * AND there is a special number option ("-n") 450 * THEN the result is the "option" itself and the 451 * option is the specially marked "number" option. 452 */ 453 if ( IS_DEC_DIGIT_CHAR(optValue) 454 && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) { 455 pOptState->pOD = \ 456 pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option; 457 (pOpts->pzCurOpt)--; 458 pOptState->optType = TOPT_SHORT; 459 return SUCCESS; 460 } 461 462 short_opt_error: 463 464 /* 465 * IF we are to stop on errors (the default, actually) 466 * THEN call the usage procedure. 467 */ 468 if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { 469 fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue); 470 (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); 471 /* NOTREACHED */ 472 _exit(EXIT_FAILURE); /* to be certain */ 473 } 474 475 return FAILURE; 476 } 477 478 /** 479 * Process option with a required argument. Long options can either have a 480 * separate command line argument, or an argument attached by the '=' 481 * character. Figure out which. 482 * 483 * @param[in,out] opts the program option descriptor 484 * @param[in,out] o_st the option processing state 485 * @returns SUCCESS or FAILURE 486 */ 487 static tSuccess 488 get_opt_arg_must(tOptions * opts, tOptState * o_st) 489 { 490 switch (o_st->optType) { 491 case TOPT_SHORT: 492 /* 493 * See if an arg string follows the flag character 494 */ 495 if (*++(opts->pzCurOpt) == NUL) 496 opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ]; 497 o_st->pzOptArg = opts->pzCurOpt; 498 break; 499 500 case TOPT_LONG: 501 /* 502 * See if an arg string has already been assigned (glued on 503 * with an `=' character) 504 */ 505 if (o_st->pzOptArg == NULL) 506 o_st->pzOptArg = opts->origArgVect[ opts->curOptIdx++ ]; 507 break; 508 509 default: 510 #ifdef DEBUG 511 fputs("AutoOpts lib error: option type not selected\n", stderr); 512 option_exits(EXIT_FAILURE); 513 #endif 514 515 case TOPT_DEFAULT: 516 /* 517 * The option was selected by default. The current token is 518 * the option argument. 519 */ 520 break; 521 } 522 523 /* 524 * Make sure we did not overflow the argument list. 525 */ 526 if (opts->curOptIdx > opts->origArgCt) { 527 fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name); 528 return FAILURE; 529 } 530 531 opts->pzCurOpt = NULL; /* next time advance to next arg */ 532 return SUCCESS; 533 } 534 535 /** 536 * Process an option with an optional argument. For short options, it looks 537 * at the character after the option character, or it consumes the next full 538 * argument. For long options, it looks for an '=' character attachment to 539 * the long option name before deciding to take the next command line 540 * argument. 541 * 542 * @param pOpts the option descriptor 543 * @param o_st a structure for managing the current processing state 544 * @returns SUCCESS or does not return 545 */ 546 static tSuccess 547 get_opt_arg_may(tOptions * pOpts, tOptState * o_st) 548 { 549 /* 550 * An option argument is optional. 551 */ 552 switch (o_st->optType) { 553 case TOPT_SHORT: 554 if (*++pOpts->pzCurOpt != NUL) 555 o_st->pzOptArg = pOpts->pzCurOpt; 556 else { 557 char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; 558 559 /* 560 * BECAUSE it is optional, we must make sure 561 * we did not find another flag and that there 562 * is such an argument. 563 */ 564 if ((pzLA == NULL) || (*pzLA == '-')) 565 o_st->pzOptArg = NULL; 566 else { 567 pOpts->curOptIdx++; /* argument found */ 568 o_st->pzOptArg = pzLA; 569 } 570 } 571 break; 572 573 case TOPT_LONG: 574 /* 575 * Look for an argument if we don't already have one (glued on 576 * with a `=' character) *AND* we are not in named argument mode 577 */ 578 if ( (o_st->pzOptArg == NULL) 579 && (! NAMED_OPTS(pOpts))) { 580 char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; 581 582 /* 583 * BECAUSE it is optional, we must make sure 584 * we did not find another flag and that there 585 * is such an argument. 586 */ 587 if ((pzLA == NULL) || (*pzLA == '-')) 588 o_st->pzOptArg = NULL; 589 else { 590 pOpts->curOptIdx++; /* argument found */ 591 o_st->pzOptArg = pzLA; 592 } 593 } 594 break; 595 596 default: 597 case TOPT_DEFAULT: 598 ao_bug(zbad_default_msg); 599 } 600 601 /* 602 * After an option with an optional argument, we will 603 * *always* start with the next option because if there 604 * were any characters following the option name/flag, 605 * they would be interpreted as the argument. 606 */ 607 pOpts->pzCurOpt = NULL; 608 return SUCCESS; 609 } 610 611 /** 612 * Process option that does not have an argument. 613 * 614 * @param[in,out] opts the program option descriptor 615 * @param[in,out] o_st the option processing state 616 * @returns SUCCESS or FAILURE 617 */ 618 static tSuccess 619 get_opt_arg_none(tOptions * pOpts, tOptState * o_st) 620 { 621 /* 622 * No option argument. Make sure next time around we find 623 * the correct option flag character for short options 624 */ 625 if (o_st->optType == TOPT_SHORT) 626 (pOpts->pzCurOpt)++; 627 628 /* 629 * It is a long option. Make sure there was no ``=xxx'' argument 630 */ 631 else if (o_st->pzOptArg != NULL) { 632 fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name); 633 return FAILURE; 634 } 635 636 /* 637 * It is a long option. Advance to next command line argument. 638 */ 639 else 640 pOpts->pzCurOpt = NULL; 641 return SUCCESS; 642 } 643 644 /** 645 * Process option. Figure out whether or not to look for an option argument. 646 * 647 * @param[in,out] opts the program option descriptor 648 * @param[in,out] o_st the option processing state 649 * @returns SUCCESS or FAILURE 650 */ 651 LOCAL tSuccess 652 get_opt_arg(tOptions * opts, tOptState * o_st) 653 { 654 o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK); 655 656 /* 657 * Disabled options and options specified to not have arguments 658 * are handled with the "none" procedure. Otherwise, check the 659 * optional flag and call either the "may" or "must" function. 660 */ 661 if ( ((o_st->flags & OPTST_DISABLED) != 0) 662 || (OPTST_GET_ARGTYPE(o_st->flags) == OPARG_TYPE_NONE)) 663 return get_opt_arg_none(opts, o_st); 664 665 if (o_st->flags & OPTST_ARG_OPTIONAL) 666 return get_opt_arg_may( opts, o_st); 667 668 return get_opt_arg_must(opts, o_st); 669 } 670 671 /** 672 * Find the option descriptor for the current option. 673 * 674 * @param[in,out] opts the program option descriptor 675 * @param[in,out] o_st the option processing state 676 * @returns SUCCESS or FAILURE 677 */ 678 LOCAL tSuccess 679 find_opt(tOptions * opts, tOptState * o_st) 680 { 681 /* 682 * IF we are continuing a short option list (e.g. -xyz...) 683 * THEN continue a single flag option. 684 * OTHERWISE see if there is room to advance and then do so. 685 */ 686 if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL)) 687 return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); 688 689 if (opts->curOptIdx >= opts->origArgCt) 690 return PROBLEM; /* NORMAL COMPLETION */ 691 692 opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ]; 693 694 /* 695 * IF all arguments must be named options, ... 696 */ 697 if (NAMED_OPTS(opts)) { 698 char * pz = opts->pzCurOpt; 699 int def; 700 tSuccess res; 701 uint16_t * def_opt; 702 703 opts->curOptIdx++; 704 705 if (*pz != '-') 706 return opt_find_long(opts, pz, o_st); 707 708 /* 709 * The name is prefixed with one or more hyphens. Strip them off 710 * and disable the "default_opt" setting. Use heavy recasting to 711 * strip off the "const" quality of the "default_opt" field. 712 */ 713 while (*(++pz) == '-') ; 714 def_opt = VOIDP(&(opts->specOptIdx.default_opt)); 715 def = *def_opt; 716 *def_opt = NO_EQUIVALENT; 717 res = opt_find_long(opts, pz, o_st); 718 *def_opt = (uint16_t)def; 719 return res; 720 } 721 722 /* 723 * Note the kind of flag/option marker 724 */ 725 if (*((opts->pzCurOpt)++) != '-') 726 return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ 727 728 /* 729 * Special hack for a hyphen by itself 730 */ 731 if (*(opts->pzCurOpt) == NUL) 732 return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ 733 734 /* 735 * The current argument is to be processed as an option argument 736 */ 737 opts->curOptIdx++; 738 739 /* 740 * We have an option marker. 741 * Test the next character for long option indication 742 */ 743 if (opts->pzCurOpt[0] == '-') { 744 if (*++(opts->pzCurOpt) == NUL) 745 /* 746 * NORMAL COMPLETION - NOT this arg, but rest are operands 747 */ 748 return PROBLEM; 749 750 /* 751 * We do not allow the hyphen to be used as a flag value. 752 * Therefore, if long options are not to be accepted, we punt. 753 */ 754 if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) { 755 fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2); 756 return FAILURE; 757 } 758 759 return opt_find_long(opts, opts->pzCurOpt, o_st); 760 } 761 762 /* 763 * If short options are not allowed, then do long 764 * option processing. Otherwise the character must be a 765 * short (i.e. single character) option. 766 */ 767 if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0) 768 return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); 769 770 return opt_find_long(opts, opts->pzCurOpt, o_st); 771 } 772 773 /** @} 774 * 775 * Local Variables: 776 * mode: C 777 * c-file-style: "stroustrup" 778 * indent-tabs-mode: nil 779 * End: 780 * end of autoopts/find.c */ 781