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