5 * Id: environment.c,v 4.13 2007/04/15 19:01:18 bkorb Exp
6 * Time-stamp: "2007-04-15 11:50:35 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.
15 * Automated Options copyright 1992-2007 Bruce Korb
17 * Automated Options is free software.
18 * You may redistribute it and/or modify it under the terms of the
19 * GNU General Public License, as published by the Free Software
20 * Foundation; either version 2, or (at your option) any later version.
22 * Automated Options is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with Automated Options. See the file "COPYING". If not,
29 * write to: The Free Software Foundation, Inc.,
30 * 51 Franklin Street, Fifth Floor,
31 * Boston, MA 02110-1301, USA.
33 * As a special exception, Bruce Korb gives permission for additional
34 * uses of the text contained in his release of AutoOpts.
36 * The exception is that, if you link the AutoOpts library with other
37 * files to produce an executable, this does not by itself cause the
38 * resulting executable to be covered by the GNU General Public License.
39 * Your use of that executable is in no way restricted on account of
40 * linking the AutoOpts library code into it.
42 * This exception does not however invalidate any other reasons why
43 * the executable file might be covered by the GNU General Public License.
45 * This exception applies only to the code released by Bruce Korb under
46 * the name AutoOpts. If you copy code from other sources under the
47 * General Public License into a copy of AutoOpts, as the General Public
48 * License permits, the exception does not apply to the code that you add
49 * in this way. To avoid misleading anyone as to the status of such
50 * modified files, you must delete this exception notice from them.
52 * If you write modifications of your own for AutoOpts, it is your choice
53 * whether to permit this exception to apply to your modifications.
54 * If you do not wish that, delete this exception notice.
57 /* = = = START-STATIC-FORWARD = = = */
58 /* static forward declarations maintained by :mkfwd */
60 checkEnvOpt(tOptState
* os
, char * env_name
,
61 tOptions
* pOpts
, teEnvPresetType type
);
62 /* = = = END-STATIC-FORWARD = = = */
65 * doPrognameEnv - check for preset values from the ${PROGNAME}
66 * environment variable. This is accomplished by parsing the text into
67 * tokens, temporarily replacing the arg vector and calling
68 * doImmediateOpts and/or doRegularOpts.
71 doPrognameEnv( tOptions
* pOpts
, teEnvPresetType type
)
73 char const* pczOptStr
= getenv( pOpts
->pzPROGNAME
);
80 * IF there is no such environment variable
81 * *or* there is, but we are doing immediate opts and there are
82 * no immediate opts to do (--help inside $PROGNAME is silly,
83 * but --no-load-defs is not, so that is marked)
84 * THEN bail out now. (
86 if ( (pczOptStr
== NULL
)
87 || ( (type
== ENV_IMM
)
88 && ((pOpts
->fOptSet
& OPTPROC_HAS_IMMED
) == 0) ) )
92 * Tokenize the string. If there's nothing of interest, we'll bail
95 pTL
= ao_string_tokenize( pczOptStr
);
100 * Substitute our $PROGNAME argument list for the real one
102 sv_argc
= pOpts
->origArgCt
;
103 sv_argv
= pOpts
->origArgVect
;
104 sv_flag
= pOpts
->fOptSet
;
107 * We add a bogus pointer to the start of the list. The program name
108 * has already been pulled from "argv", so it won't get dereferenced.
109 * The option scanning code will skip the "program name" at the start
110 * of this list of tokens, so we accommodate this way ....
112 pOpts
->origArgVect
= (char**)(pTL
->tkn_list
- 1);
113 pOpts
->origArgCt
= pTL
->tkn_ct
+ 1;
114 pOpts
->fOptSet
&= ~OPTPROC_ERRSTOP
;
116 pOpts
->curOptIdx
= 1;
117 pOpts
->pzCurOpt
= NULL
;
122 * We know the OPTPROC_HAS_IMMED bit is set.
124 (void)doImmediateOpts( pOpts
);
128 (void)doRegularOpts( pOpts
);
133 * Only to immediate opts if the OPTPROC_HAS_IMMED bit is set.
135 if (pOpts
->fOptSet
& OPTPROC_HAS_IMMED
) {
136 (void)doImmediateOpts( pOpts
);
137 pOpts
->curOptIdx
= 1;
138 pOpts
->pzCurOpt
= NULL
;
140 (void)doRegularOpts( pOpts
);
145 * Free up the temporary arg vector and restore the original program args.
148 pOpts
->origArgVect
= sv_argv
;
149 pOpts
->origArgCt
= sv_argc
;
150 pOpts
->fOptSet
= sv_flag
;
154 checkEnvOpt(tOptState
* os
, char * env_name
,
155 tOptions
* pOpts
, teEnvPresetType type
)
157 os
->pzOptArg
= getenv( env_name
);
158 if (os
->pzOptArg
== NULL
)
161 os
->flags
= OPTST_PRESET
| OPTST_ALLOC_ARG
| os
->pOD
->fOptState
;
162 os
->optType
= TOPT_UNDEFINED
;
164 if ( (os
->pOD
->pz_DisablePfx
!= NULL
)
165 && (streqvcmp( os
->pzOptArg
, os
->pOD
->pz_DisablePfx
) == 0)) {
166 os
->flags
|= OPTST_DISABLED
;
173 * Process only immediate actions
175 if (DO_IMMEDIATELY(os
->flags
))
181 * Process only NON immediate actions
183 if (DO_NORMALLY(os
->flags
) || DO_SECOND_TIME(os
->flags
))
187 default: /* process everything */
192 * Make sure the option value string is persistent and consistent.
194 * The interpretation of the option value depends
195 * on the type of value argument the option takes
197 if (os
->pzOptArg
!= NULL
) {
198 if (OPTST_GET_ARGTYPE(os
->pOD
->fOptState
) == OPARG_TYPE_NONE
) {
200 } else if ( (os
->pOD
->fOptState
& OPTST_ARG_OPTIONAL
)
201 && (*os
->pzOptArg
== NUL
)) {
203 } else if (*os
->pzOptArg
== NUL
) {
206 AGDUPSTR( os
->pzOptArg
, os
->pzOptArg
, "option argument" );
207 os
->flags
|= OPTST_ALLOC_ARG
;
211 handleOption( pOpts
, os
);
215 * doEnvPresets - check for preset values from the envrionment
216 * This routine should process in all, immediate or normal modes....
219 doEnvPresets( tOptions
* pOpts
, teEnvPresetType type
)
225 char zEnvName
[ AO_NAME_SIZE
];
228 * Finally, see if we are to look at the environment
229 * variables for initial values.
231 if ((pOpts
->fOptSet
& OPTPROC_ENVIRON
) == 0)
234 doPrognameEnv( pOpts
, type
);
236 ct
= pOpts
->presetOptCt
;
237 st
.pOD
= pOpts
->pOptDesc
;
239 pzFlagName
= zEnvName
240 + snprintf( zEnvName
, sizeof( zEnvName
), "%s_", pOpts
->pzPROGNAME
);
241 spaceLeft
= AO_NAME_SIZE
- (pzFlagName
- zEnvName
) - 1;
243 for (;ct
-- > 0; st
.pOD
++) {
245 * If presetting is disallowed, then skip this entry
247 if ( ((st
.pOD
->fOptState
& OPTST_NO_INIT
) != 0)
248 || (st
.pOD
->optEquivIndex
!= NO_EQUIVALENT
) )
252 * IF there is no such environment variable,
253 * THEN skip this entry, too.
255 if (strlen( st
.pOD
->pz_NAME
) >= spaceLeft
)
259 * Set up the option state
261 strcpy( pzFlagName
, st
.pOD
->pz_NAME
);
262 checkEnvOpt(&st
, zEnvName
, pOpts
, type
);
266 * Special handling for ${PROGNAME_LOAD_OPTS}
268 if (pOpts
->specOptIdx
.save_opts
!= 0) {
269 st
.pOD
= pOpts
->pOptDesc
+ pOpts
->specOptIdx
.save_opts
+ 1;
270 strcpy( pzFlagName
, st
.pOD
->pz_NAME
);
271 checkEnvOpt(&st
, zEnvName
, pOpts
, type
);
278 * c-file-style: "stroustrup"
279 * indent-tabs-mode: nil
281 * end of autoopts/environment.c */