5 * Id: 56abb301f50605ec5bae137ded730e330d8d7735
6 * Time-stamp: "2009-11-01 10:50:34 bkorb"
8 * This file contains all of the routines that must be linked into
9 * an executable to use the generated option processing. The optional
10 * routines are in separately compiled modules so that they will not
11 * necessarily be linked in.
13 * This file is part of AutoOpts, a companion to AutoGen.
14 * AutoOpts is free software.
15 * AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved
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.
21 * The GNU Lesser General Public License, version 3 or later
22 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
24 * The Modified Berkeley Software Distribution License
25 * See the file "COPYING.mbsd"
27 * These files have the following md5sums:
29 * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
30 * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
31 * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
34 static char const zNil
[] = "";
36 /* = = = START-STATIC-FORWARD = = = */
37 /* static forward declarations maintained by mk-fwd */
39 findOptDesc( tOptions
* pOpts
, tOptState
* pOptState
);
42 next_opt_arg_must(tOptions
* pOpts
, tOptState
* pOptState
);
45 next_opt_arg_may(tOptions
* pOpts
, tOptState
* pOptState
);
48 next_opt_arg_none(tOptions
* pOpts
, tOptState
* pOptState
);
51 nextOption(tOptions
* pOpts
, tOptState
* pOptState
);
54 doPresets( tOptions
* pOpts
);
57 checkConsistency( tOptions
* pOpts
);
58 /* = = = END-STATIC-FORWARD = = = */
61 ao_malloc( size_t sz
)
63 void * res
= malloc(sz
);
65 fprintf( stderr
, "malloc of %d bytes failed\n", (int)sz
);
71 #define malloc(_s) ao_malloc(_s)
74 ao_realloc( void *p
, size_t sz
)
76 void * res
= realloc(p
, sz
);
78 fprintf( stderr
, "realloc of %d bytes at 0x%p failed\n", (int)sz
, p
);
84 #define realloc(_p,_s) ao_realloc(_p,_s)
94 #define free(_p) ao_free(_p)
98 ao_strdup( char const *str
)
100 char * res
= strdup(str
);
102 fprintf(stderr
, "strdup of %d byte string failed\n", (int)strlen(str
));
103 exit( EXIT_FAILURE
);
108 #define strdup(_p) ao_strdup(_p)
110 #ifndef HAVE_PATHFIND
111 # include "compat/pathfind.c"
114 #ifndef HAVE_SNPRINTF
115 # include "compat/snprintf.c"
119 # include "compat/strdup.c"
123 # include "compat/strchr.c"
129 * This routine handles equivalencing, sets the option state flags and
130 * invokes the handler procedure, if any.
133 handleOption( tOptions
* pOpts
, tOptState
* pOptState
)
136 * Save a copy of the option procedure pointer.
137 * If this is an equivalence class option, we still want this proc.
139 tOptDesc
* pOD
= pOptState
->pOD
;
140 tOptProc
* pOP
= pOD
->pOptProc
;
141 if (pOD
->fOptState
& OPTST_ALLOC_ARG
)
142 AGFREE(pOD
->optArg
.argString
);
144 pOD
->optArg
.argString
= pOptState
->pzOptArg
;
147 * IF we are presetting options, then we will ignore any un-presettable
148 * options. They are the ones either marked as such.
150 if ( ((pOpts
->fOptSet
& OPTPROC_PRESETTING
) != 0)
151 && ((pOD
->fOptState
& OPTST_NO_INIT
) != 0)
156 * IF this is an equivalence class option,
158 * Save the option value that got us to this option
159 * entry. (It may not be pOD->optChar[0], if this is an
160 * equivalence entry.)
161 * set the pointer to the equivalence class base
163 if (pOD
->optEquivIndex
!= NO_EQUIVALENT
) {
164 tOptDesc
* p
= pOpts
->pOptDesc
+ pOD
->optEquivIndex
;
167 * IF the current option state has not been defined (set on the
168 * command line), THEN we will allow continued resetting of
169 * the value. Once "defined", then it must not change.
171 if ((pOD
->fOptState
& OPTST_DEFINED
) != 0) {
173 * The equivalenced-to option has been found on the command
174 * line before. Make sure new occurrences are the same type.
176 * IF this option has been previously equivalenced and
177 * it was not the same equivalenced-to option,
178 * THEN we have a usage problem.
180 if (p
->optActualIndex
!= pOD
->optIndex
) {
181 fprintf( stderr
, (char*)zMultiEquiv
, p
->pz_Name
, pOD
->pz_Name
,
182 (pOpts
->pOptDesc
+ p
->optActualIndex
)->pz_Name
);
187 * Set the equivalenced-to actual option index to no-equivalent
188 * so that we set all the entries below. This option may either
189 * never have been selected before, or else it was selected by
190 * some sort of "presetting" mechanism.
192 p
->optActualIndex
= NO_EQUIVALENT
;
195 if (p
->optActualIndex
!= pOD
->optIndex
) {
197 * First time through, copy over the state
198 * and add in the equivalence flag
200 p
->optActualValue
= pOD
->optValue
;
201 p
->optActualIndex
= pOD
->optIndex
;
202 pOptState
->flags
|= OPTST_EQUIVALENCE
;
206 * Copy the most recent option argument. set membership state
207 * is kept in ``p->optCookie''. Do not overwrite.
209 p
->optArg
.argString
= pOD
->optArg
.argString
;
213 pOD
->optActualValue
= pOD
->optValue
;
214 pOD
->optActualIndex
= pOD
->optIndex
;
217 pOD
->fOptState
&= OPTST_PERSISTENT_MASK
;
218 pOD
->fOptState
|= (pOptState
->flags
& ~OPTST_PERSISTENT_MASK
);
221 * Keep track of count only for DEFINED (command line) options.
222 * IF we have too many, build up an error message and bail.
224 if ( (pOD
->fOptState
& OPTST_DEFINED
)
225 && (++pOD
->optOccCt
> pOD
->optMaxCt
) ) {
227 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0) {
229 (pOD
->optEquivIndex
!= NO_EQUIVALENT
) ? zEquiv
: zNil
;
231 fputs( zErrOnly
, stderr
);
233 if (pOD
->optMaxCt
> 1)
234 fprintf(stderr
, zAtMost
, pOD
->optMaxCt
, pOD
->pz_Name
, pzEqv
);
236 fprintf(stderr
, zOnlyOne
, pOD
->pz_Name
, pzEqv
);
243 * If provided a procedure to call, call it
246 (*pOP
)( pOpts
, pOD
);
252 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
254 * HUNT FOR OPTIONS IN THE ARGUMENT LIST
256 * The next four procedures are "private" to nextOption().
257 * nextOption() uses findOptDesc() to find the next descriptor and it, in
258 * turn, uses longOptionFind() and shortOptionFind() to actually do the hunt.
262 * Find the long option descriptor for the current option
265 longOptionFind( tOptions
* pOpts
, char* pzOptName
, tOptState
* pOptState
)
267 ag_bool disable
= AG_FALSE
;
268 char* pzEq
= strchr( pzOptName
, '=' );
269 tOptDesc
* pOD
= pOpts
->pOptDesc
;
271 int idxLim
= pOpts
->optCt
;
275 char opt_name_buf
[128];
278 * IF the value is attached to the name,
279 * copy it off so we can NUL terminate.
282 nameLen
= (int)(pzEq
- pzOptName
);
283 if (nameLen
>= sizeof(opt_name_buf
))
285 memcpy(opt_name_buf
, pzOptName
, nameLen
);
286 opt_name_buf
[nameLen
] = NUL
;
287 pzOptName
= opt_name_buf
;
290 } else nameLen
= strlen( pzOptName
);
294 if ( (pOD
->fOptState
!= (OPTST_OMITTED
| OPTST_NO_INIT
))
295 || (pOD
->pz_Name
== NULL
))
298 else assert(pOD
->pz_Name
!= NULL
);
300 if (strneqvcmp( pzOptName
, pOD
->pz_Name
, nameLen
) == 0) {
302 * IF we have a complete match
303 * THEN it takes priority over any already located partial
305 if (pOD
->pz_Name
[ nameLen
] == NUL
) {
313 * IF there is a disable name
314 * *AND* no argument value has been supplied
315 * (disabled options may have no argument)
316 * *AND* the option name matches the disable name
319 else if ( (pOD
->pz_DisableName
!= NULL
)
320 && (strneqvcmp(pzOptName
, pOD
->pz_DisableName
, nameLen
) == 0)
325 * IF we have a complete match
326 * THEN it takes priority over any already located partial
328 if (pOD
->pz_DisableName
[ nameLen
] == NUL
) {
339 * We found a partial match, either regular or disabling.
340 * Remember the index for later.
347 } while (pOD
++, (++idx
< idxLim
));
350 * Make sure we either found an exact match or found only one partial
353 pOD
= pOpts
->pOptDesc
+ matchIdx
;
356 fprintf(stderr
, zDisabledErr
, pOpts
->pzProgName
, pOD
->pz_Name
);
357 if (pOD
->pzText
!= NULL
)
358 fprintf(stderr
, " -- %s", pOD
->pzText
);
360 (*pOpts
->pUsageProc
)(pOpts
, EXIT_FAILURE
);
365 * IF we found a disablement name,
366 * THEN set the bit in the callers' flag word
369 pOptState
->flags
|= OPTST_DISABLED
;
371 pOptState
->pOD
= pOD
;
372 pOptState
->pzOptArg
= pzEq
;
373 pOptState
->optType
= TOPT_LONG
;
378 * IF there is no equal sign
379 * *AND* we are using named arguments
380 * *AND* there is a default named option,
381 * THEN return that option.
385 && (pOpts
->specOptIdx
.default_opt
!= NO_EQUIVALENT
)) {
386 pOptState
->pOD
= pOpts
->pOptDesc
+ pOpts
->specOptIdx
.default_opt
;
388 pOptState
->pzOptArg
= pzOptName
;
389 pOptState
->optType
= TOPT_DEFAULT
;
394 * IF we are to stop on errors (the default, actually)
395 * THEN call the usage procedure.
397 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0) {
398 fprintf(stderr
, (matchCt
== 0) ? zIllOptStr
: zAmbigOptStr
,
399 pOpts
->pzProgPath
, pzOptName
);
400 (*pOpts
->pUsageProc
)(pOpts
, EXIT_FAILURE
);
410 * Find the short option descriptor for the current option
413 shortOptionFind( tOptions
* pOpts
, uint_t optValue
, tOptState
* pOptState
)
415 tOptDesc
* pRes
= pOpts
->pOptDesc
;
416 int ct
= pOpts
->optCt
;
419 * Search the option list
422 if (optValue
!= pRes
->optValue
)
425 if (SKIP_OPT(pRes
)) {
426 if ( (pRes
->fOptState
== (OPTST_OMITTED
| OPTST_NO_INIT
))
427 && (pRes
->pz_Name
!= NULL
)) {
428 fprintf(stderr
, zDisabledErr
, pOpts
->pzProgPath
, pRes
->pz_Name
);
429 if (pRes
->pzText
!= NULL
)
430 fprintf(stderr
, " -- %s", pRes
->pzText
);
432 (*pOpts
->pUsageProc
)(pOpts
, EXIT_FAILURE
);
435 goto short_opt_error
;
438 pOptState
->pOD
= pRes
;
439 pOptState
->optType
= TOPT_SHORT
;
442 } while (pRes
++, --ct
> 0);
445 * IF the character value is a digit
446 * AND there is a special number option ("-n")
447 * THEN the result is the "option" itself and the
448 * option is the specially marked "number" option.
450 if ( IS_DEC_DIGIT_CHAR(optValue
)
451 && (pOpts
->specOptIdx
.number_option
!= NO_EQUIVALENT
) ) {
453 pRes
= pOpts
->pOptDesc
+ pOpts
->specOptIdx
.number_option
;
455 pOptState
->optType
= TOPT_SHORT
;
462 * IF we are to stop on errors (the default, actually)
463 * THEN call the usage procedure.
465 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0) {
466 fprintf( stderr
, zIllOptChr
, pOpts
->pzProgPath
, optValue
);
467 (*pOpts
->pUsageProc
)( pOpts
, EXIT_FAILURE
);
477 * Find the option descriptor for the current option
480 findOptDesc( tOptions
* pOpts
, tOptState
* pOptState
)
483 * IF we are continuing a short option list (e.g. -xyz...)
484 * THEN continue a single flag option.
485 * OTHERWISE see if there is room to advance and then do so.
487 if ((pOpts
->pzCurOpt
!= NULL
) && (*pOpts
->pzCurOpt
!= NUL
))
488 return shortOptionFind( pOpts
, (tAoUC
)*(pOpts
->pzCurOpt
), pOptState
);
490 if (pOpts
->curOptIdx
>= pOpts
->origArgCt
)
491 return PROBLEM
; /* NORMAL COMPLETION */
493 pOpts
->pzCurOpt
= pOpts
->origArgVect
[ pOpts
->curOptIdx
];
496 * IF all arguments must be named options, ...
498 if (NAMED_OPTS(pOpts
)) {
499 char * pz
= pOpts
->pzCurOpt
;
507 return longOptionFind(pOpts
, pz
, pOptState
);
510 * The name is prefixed with one or more hyphens. Strip them off
511 * and disable the "default_opt" setting. Use heavy recasting to
512 * strip off the "const" quality of the "default_opt" field.
514 while (*(++pz
) == '-') ;
515 def_opt
= (void *)&(pOpts
->specOptIdx
.default_opt
);
517 *def_opt
= NO_EQUIVALENT
;
518 res
= longOptionFind(pOpts
, pz
, pOptState
);
524 * Note the kind of flag/option marker
526 if (*((pOpts
->pzCurOpt
)++) != '-')
527 return PROBLEM
; /* NORMAL COMPLETION - this + rest are operands */
530 * Special hack for a hyphen by itself
532 if (*(pOpts
->pzCurOpt
) == NUL
)
533 return PROBLEM
; /* NORMAL COMPLETION - this + rest are operands */
536 * The current argument is to be processed as an option argument
541 * We have an option marker.
542 * Test the next character for long option indication
544 if (pOpts
->pzCurOpt
[0] == '-') {
545 if (*++(pOpts
->pzCurOpt
) == NUL
)
547 * NORMAL COMPLETION - NOT this arg, but rest are operands
552 * We do not allow the hyphen to be used as a flag value.
553 * Therefore, if long options are not to be accepted, we punt.
555 if ((pOpts
->fOptSet
& OPTPROC_LONGOPT
) == 0) {
556 fprintf( stderr
, zIllOptStr
, pOpts
->pzProgPath
,
557 zIllegal
, pOpts
->pzCurOpt
-2 );
561 return longOptionFind( pOpts
, pOpts
->pzCurOpt
, pOptState
);
565 * If short options are not allowed, then do long
566 * option processing. Otherwise the character must be a
567 * short (i.e. single character) option.
569 if ((pOpts
->fOptSet
& OPTPROC_SHORTOPT
) != 0)
570 return shortOptionFind( pOpts
, (tAoUC
)*(pOpts
->pzCurOpt
), pOptState
);
572 return longOptionFind( pOpts
, pOpts
->pzCurOpt
, pOptState
);
577 next_opt_arg_must(tOptions
* pOpts
, tOptState
* pOptState
)
580 * An option argument is required. Long options can either have
581 * a separate command line argument, or an argument attached by
582 * the '=' character. Figure out which.
584 switch (pOptState
->optType
) {
587 * See if an arg string follows the flag character
589 if (*++(pOpts
->pzCurOpt
) == NUL
)
590 pOpts
->pzCurOpt
= pOpts
->origArgVect
[ pOpts
->curOptIdx
++ ];
591 pOptState
->pzOptArg
= pOpts
->pzCurOpt
;
596 * See if an arg string has already been assigned (glued on
597 * with an `=' character)
599 if (pOptState
->pzOptArg
== NULL
)
600 pOptState
->pzOptArg
= pOpts
->origArgVect
[ pOpts
->curOptIdx
++ ];
605 fputs( "AutoOpts lib error: option type not selected\n",
607 exit( EXIT_FAILURE
);
612 * The option was selected by default. The current token is
613 * the option argument.
619 * Make sure we did not overflow the argument list.
621 if (pOpts
->curOptIdx
> pOpts
->origArgCt
) {
622 fprintf( stderr
, zMisArg
, pOpts
->pzProgPath
,
623 pOptState
->pOD
->pz_Name
);
627 pOpts
->pzCurOpt
= NULL
; /* next time advance to next arg */
633 next_opt_arg_may(tOptions
* pOpts
, tOptState
* pOptState
)
636 * An option argument is optional.
638 switch (pOptState
->optType
) {
640 if (*++pOpts
->pzCurOpt
!= NUL
)
641 pOptState
->pzOptArg
= pOpts
->pzCurOpt
;
643 char* pzLA
= pOpts
->origArgVect
[ pOpts
->curOptIdx
];
646 * BECAUSE it is optional, we must make sure
647 * we did not find another flag and that there
648 * is such an argument.
650 if ((pzLA
== NULL
) || (*pzLA
== '-'))
651 pOptState
->pzOptArg
= NULL
;
653 pOpts
->curOptIdx
++; /* argument found */
654 pOptState
->pzOptArg
= pzLA
;
661 * Look for an argument if we don't already have one (glued on
662 * with a `=' character) *AND* we are not in named argument mode
664 if ( (pOptState
->pzOptArg
== NULL
)
665 && (! NAMED_OPTS(pOpts
))) {
666 char* pzLA
= pOpts
->origArgVect
[ pOpts
->curOptIdx
];
669 * BECAUSE it is optional, we must make sure
670 * we did not find another flag and that there
671 * is such an argument.
673 if ((pzLA
== NULL
) || (*pzLA
== '-'))
674 pOptState
->pzOptArg
= NULL
;
676 pOpts
->curOptIdx
++; /* argument found */
677 pOptState
->pzOptArg
= pzLA
;
684 fputs(zAO_Woops
, stderr
);
689 * After an option with an optional argument, we will
690 * *always* start with the next option because if there
691 * were any characters following the option name/flag,
692 * they would be interpreted as the argument.
694 pOpts
->pzCurOpt
= NULL
;
700 next_opt_arg_none(tOptions
* pOpts
, tOptState
* pOptState
)
703 * No option argument. Make sure next time around we find
704 * the correct option flag character for short options
706 if (pOptState
->optType
== TOPT_SHORT
)
710 * It is a long option. Make sure there was no ``=xxx'' argument
712 else if (pOptState
->pzOptArg
!= NULL
) {
713 fprintf(stderr
, zNoArg
, pOpts
->pzProgPath
, pOptState
->pOD
->pz_Name
);
718 * It is a long option. Advance to next command line argument.
721 pOpts
->pzCurOpt
= NULL
;
728 * Find the option descriptor and option argument (if any) for the
729 * next command line argument. DO NOT modify the descriptor. Put
730 * all the state in the state argument so that the option can be skipped
731 * without consequence (side effect).
734 nextOption(tOptions
* pOpts
, tOptState
* pOptState
)
738 res
= findOptDesc( pOpts
, pOptState
);
739 if (! SUCCESSFUL( res
))
743 if ( ((pOptState
->flags
& OPTST_DEFINED
) != 0)
744 && ((pOptState
->pOD
->fOptState
& OPTST_NO_COMMAND
) != 0)) {
745 fprintf(stderr
, zNotCmdOpt
, pOptState
->pOD
->pz_Name
);
749 pOptState
->flags
|= (pOptState
->pOD
->fOptState
& OPTST_PERSISTENT_MASK
);
752 * Figure out what to do about option arguments. An argument may be
753 * required, not associated with the option, or be optional. We detect the
754 * latter by examining for an option marker on the next possible argument.
755 * Disabled mode option selection also disables option arguments.
758 enum { ARG_NONE
, ARG_MAY
, ARG_MUST
} arg_type
= ARG_NONE
;
761 if ((pOptState
->flags
& OPTST_DISABLED
) != 0)
764 else if (OPTST_GET_ARGTYPE(pOptState
->flags
) == OPARG_TYPE_NONE
)
767 else if (pOptState
->flags
& OPTST_ARG_OPTIONAL
)
774 case ARG_MUST
: res
= next_opt_arg_must(pOpts
, pOptState
); break;
775 case ARG_MAY
: res
= next_opt_arg_may( pOpts
, pOptState
); break;
776 case ARG_NONE
: res
= next_opt_arg_none(pOpts
, pOptState
); break;
784 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
788 * The next several routines do the immediate action pass on the command
789 * line options, then the environment variables, then the config files in
790 * reverse order. Once done with that, the order is reversed and all
791 * the config files and environment variables are processed again, this
792 * time only processing the non-immediate action options. doPresets()
793 * will then return for optionProcess() to do the final pass on the command
798 * doImmediateOpts - scan the command line for immediate action options
801 doImmediateOpts( tOptions
* pOpts
)
803 pOpts
->curOptIdx
= 1; /* start by skipping program name */
804 pOpts
->pzCurOpt
= NULL
;
807 * Examine all the options from the start. We process any options that
808 * are marked for immediate processing.
811 tOptState optState
= OPTSTATE_INITIALIZER(PRESET
);
813 switch (nextOption( pOpts
, &optState
)) {
814 case FAILURE
: goto optionsDone
;
815 case PROBLEM
: return SUCCESS
; /* no more args */
820 * IF this *is* an immediate-attribute option, then do it.
822 if (! DO_IMMEDIATELY(optState
.flags
))
825 if (! SUCCESSFUL( handleOption( pOpts
, &optState
)))
829 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0)
830 (*pOpts
->pUsageProc
)( pOpts
, EXIT_FAILURE
);
836 doRegularOpts( tOptions
* pOpts
)
839 * Now, process all the options from our current position onward.
840 * (This allows interspersed options and arguments for the few
841 * non-standard programs that require it.)
844 tOptState optState
= OPTSTATE_INITIALIZER(DEFINED
);
846 switch (nextOption( pOpts
, &optState
)) {
847 case FAILURE
: goto optionsDone
;
848 case PROBLEM
: return SUCCESS
; /* no more args */
853 * IF this is not being processed normally (i.e. is immediate action)
854 * THEN skip it (unless we are supposed to do it a second time).
856 if (! DO_NORMALLY(optState
.flags
)) {
857 if (! DO_SECOND_TIME(optState
.flags
))
859 optState
.pOD
->optOccCt
--; /* don't count last time */
862 if (! SUCCESSFUL( handleOption( pOpts
, &optState
)))
865 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0)
866 (*pOpts
->pUsageProc
)( pOpts
, EXIT_FAILURE
);
872 * doPresets - check for preset values from a config file or the envrionment
875 doPresets( tOptions
* pOpts
)
877 tOptDesc
* pOD
= NULL
;
879 if (! SUCCESSFUL( doImmediateOpts( pOpts
)))
883 * IF this option set has a --save-opts option, then it also
884 * has a --load-opts option. See if a command line option has disabled
887 if ( (pOpts
->specOptIdx
.save_opts
!= NO_EQUIVALENT
)
888 && (pOpts
->specOptIdx
.save_opts
!= 0)) {
889 pOD
= pOpts
->pOptDesc
+ pOpts
->specOptIdx
.save_opts
+ 1;
890 if (DISABLED_OPT(pOD
))
895 * Until we return from this procedure, disable non-presettable opts
897 pOpts
->fOptSet
|= OPTPROC_PRESETTING
;
899 * IF there are no config files,
900 * THEN do any environment presets and leave.
902 if (pOpts
->papzHomeList
== NULL
) {
903 doEnvPresets( pOpts
, ENV_ALL
);
906 doEnvPresets( pOpts
, ENV_IMM
);
909 * Check to see if environment variables have disabled presetting.
911 if ((pOD
!= NULL
) && ! DISABLED_OPT(pOD
))
912 internalFileLoad( pOpts
);
915 * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
916 * variable options. Only the loading of .rc files.
918 doEnvPresets( pOpts
, ENV_NON_IMM
);
920 pOpts
->fOptSet
&= ~OPTPROC_PRESETTING
;
926 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
928 * VERIFY OPTION CONSISTENCY
930 * Make sure that the argument list passes our consistency tests.
933 checkConsistency( tOptions
* pOpts
)
936 tOptDesc
* pOD
= pOpts
->pOptDesc
;
937 int oCt
= pOpts
->presetOptCt
;
940 * FOR each of "oCt" options, ...
943 const int* pMust
= pOD
->pOptMust
;
944 const int* pCant
= pOD
->pOptCant
;
947 * IF the current option was provided on the command line
948 * THEN ensure that any "MUST" requirements are not
949 * "DEFAULT" (unspecified) *AND* ensure that any
950 * "CANT" options have not been SET or DEFINED.
952 if (SELECTED_OPT(pOD
)) {
953 if (pMust
!= NULL
) for (;;) {
954 tOptDesc
* p
= pOpts
->pOptDesc
+ *(pMust
++);
956 const tOptDesc
* pN
= pOpts
->pOptDesc
+ pMust
[-1];
958 fprintf( stderr
, zReqFmt
, pOD
->pz_Name
, pN
->pz_Name
);
961 if (*pMust
== NO_EQUIVALENT
)
965 if (pCant
!= NULL
) for (;;) {
966 tOptDesc
* p
= pOpts
->pOptDesc
+ *(pCant
++);
967 if (SELECTED_OPT(p
)) {
968 const tOptDesc
* pN
= pOpts
->pOptDesc
+ pCant
[-1];
970 fprintf( stderr
, zCantFmt
, pOD
->pz_Name
, pN
->pz_Name
);
973 if (*pCant
== NO_EQUIVALENT
)
979 * IF this option is not equivalenced to another,
980 * OR it is equivalenced to itself (is the equiv. root)
981 * THEN we need to make sure it occurs often enough.
983 if ( (pOD
->optEquivIndex
== NO_EQUIVALENT
)
984 || (pOD
->optEquivIndex
== pOD
->optIndex
) ) do {
986 * IF the occurrence counts have been satisfied,
987 * THEN there is no problem.
989 if (pOD
->optOccCt
>= pOD
->optMinCt
)
993 * IF MUST_SET means SET and PRESET are okay,
994 * so min occurrence count doesn't count
996 if ( (pOD
->fOptState
& OPTST_MUST_SET
)
997 && (pOD
->fOptState
& (OPTST_PRESET
| OPTST_SET
)) )
1001 if (pOD
->optMinCt
> 1)
1002 fprintf( stderr
, zNotEnough
, pOD
->pz_Name
, pOD
->optMinCt
);
1003 else fprintf( stderr
, zNeedOne
, pOD
->pz_Name
);
1012 * IF we are stopping on errors, check to see if any remaining
1013 * arguments are required to be there or prohibited from being there.
1015 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0) {
1018 * Check for prohibition
1020 if ((pOpts
->fOptSet
& OPTPROC_NO_ARGS
) != 0) {
1021 if (pOpts
->origArgCt
> pOpts
->curOptIdx
) {
1022 fprintf( stderr
, zNoArgs
, pOpts
->pzProgName
);
1028 * ELSE not prohibited, check for being required
1030 else if ((pOpts
->fOptSet
& OPTPROC_ARGS_REQ
) != 0) {
1031 if (pOpts
->origArgCt
<= pOpts
->curOptIdx
) {
1032 fprintf( stderr
, zArgsMust
, pOpts
->pzProgName
);
1042 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1044 * THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE
1046 /*=--subblock=arg=arg_type,arg_name,arg_desc =*/
1049 * header: your-opts.h
1053 * These are the routines that libopts users may call directly from their
1054 * code. There are several other routines that can be called by code
1055 * generated by the libopts option templates, but they are not to be
1056 * called from any other user code. The @file{options.h} header is
1057 * fairly clear about this, too.
1060 /*=export_func optionProcess
1062 * what: this is the main option processing routine
1064 * arg: + tOptions* + pOpts + program options descriptor +
1065 * arg: + int + argc + program arg count +
1066 * arg: + char** + argv + program arg vector +
1069 * ret_desc: the count of the arguments processed
1073 * This is the main entry point for processing options. It is intended
1074 * that this procedure be called once at the beginning of the execution of
1075 * a program. Depending on options selected earlier, it is sometimes
1076 * necessary to stop and restart option processing, or to select completely
1077 * different sets of options. This can be done easily, but you generally
1078 * do not want to do this.
1080 * The number of arguments processed always includes the program name.
1081 * If one of the arguments is "--", then it is counted and the processing
1082 * stops. If an error was encountered and errors are to be tolerated, then
1083 * the returned value is the index of the argument causing the error.
1084 * A hyphen by itself ("-") will also cause processing to stop and will
1085 * @emph{not} be counted among the processed arguments. A hyphen by itself
1086 * is treated as an operand. Encountering an operand stops option
1089 * err: Errors will cause diagnostics to be printed. @code{exit(3)} may
1090 * or may not be called. It depends upon whether or not the options
1091 * were generated with the "allow-errors" attribute, or if the
1092 * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked.
1100 if (! SUCCESSFUL( validateOptionsStruct( pOpts
, argVect
[0] )))
1101 exit( EX_SOFTWARE
);
1104 * Establish the real program name, the program full path,
1105 * and do all the presetting the first time thru only.
1107 if ((pOpts
->fOptSet
& OPTPROC_INITDONE
) == 0) {
1108 pOpts
->origArgCt
= argCt
;
1109 pOpts
->origArgVect
= argVect
;
1110 pOpts
->fOptSet
|= OPTPROC_INITDONE
;
1112 if (! SUCCESSFUL( doPresets( pOpts
)))
1116 * IF option name conversion was suppressed but it is not suppressed
1117 * for the command line, then it's time to translate option names.
1118 * Usage text will not get retranslated.
1120 if ( ((pOpts
->fOptSet
& OPTPROC_TRANSLATE
) != 0)
1121 && (pOpts
->pTransProc
!= NULL
)
1122 && ((pOpts
->fOptSet
& OPTPROC_NO_XLAT_MASK
)
1123 == OPTPROC_NXLAT_OPT_CFG
) ) {
1125 pOpts
->fOptSet
&= ~OPTPROC_NXLAT_OPT_CFG
;
1126 (*pOpts
->pTransProc
)();
1129 if ((pOpts
->fOptSet
& OPTPROC_REORDER
) != 0)
1130 optionSort( pOpts
);
1132 pOpts
->curOptIdx
= 1;
1133 pOpts
->pzCurOpt
= NULL
;
1137 * IF we are (re)starting,
1138 * THEN reset option location
1140 else if (pOpts
->curOptIdx
<= 0) {
1141 pOpts
->curOptIdx
= 1;
1142 pOpts
->pzCurOpt
= NULL
;
1145 if (! SUCCESSFUL( doRegularOpts( pOpts
)))
1146 return pOpts
->origArgCt
;
1149 * IF there were no errors
1150 * AND we have RC/INI files
1151 * AND there is a request to save the files
1152 * THEN do that now before testing for conflicts.
1153 * (conflicts are ignored in preset options)
1155 if ( (pOpts
->specOptIdx
.save_opts
!= NO_EQUIVALENT
)
1156 && (pOpts
->specOptIdx
.save_opts
!= 0)) {
1157 tOptDesc
* pOD
= pOpts
->pOptDesc
+ pOpts
->specOptIdx
.save_opts
;
1159 if (SELECTED_OPT( pOD
)) {
1160 optionSaveFile( pOpts
);
1161 exit( EXIT_SUCCESS
);
1166 * IF we are checking for errors,
1167 * THEN look for too few occurrences of required options
1169 if ((pOpts
->fOptSet
& OPTPROC_ERRSTOP
) != 0) {
1170 if (checkConsistency( pOpts
) != 0)
1171 (*pOpts
->pUsageProc
)( pOpts
, EXIT_FAILURE
);
1174 return pOpts
->curOptIdx
;
1180 * c-file-style: "stroustrup"
1181 * indent-tabs-mode: nil
1183 * end of autoopts/autoopts.c */