Sync usage with man page.
[netbsd-mini2440.git] / dist / ntp / libopts / environment.c
blob1f1d051f7b39a658afc097ed32ac1eb8470eea44
1 /* $NetBSD$ */
4 /*
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 */
59 static void
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.
70 LOCAL void
71 doPrognameEnv( tOptions* pOpts, teEnvPresetType type )
73 char const* pczOptStr = getenv( pOpts->pzPROGNAME );
74 token_list_t* pTL;
75 int sv_argc;
76 tAoUI sv_flag;
77 char** sv_argv;
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) ) )
89 return;
92 * Tokenize the string. If there's nothing of interest, we'll bail
93 * here immediately.
95 pTL = ao_string_tokenize( pczOptStr );
96 if (pTL == NULL)
97 return;
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;
119 switch (type) {
120 case ENV_IMM:
122 * We know the OPTPROC_HAS_IMMED bit is set.
124 (void)doImmediateOpts( pOpts );
125 break;
127 case ENV_NON_IMM:
128 (void)doRegularOpts( pOpts );
129 break;
131 default:
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 );
141 break;
145 * Free up the temporary arg vector and restore the original program args.
147 free( pTL );
148 pOpts->origArgVect = sv_argv;
149 pOpts->origArgCt = sv_argc;
150 pOpts->fOptSet = sv_flag;
153 static void
154 checkEnvOpt(tOptState * os, char * env_name,
155 tOptions* pOpts, teEnvPresetType type)
157 os->pzOptArg = getenv( env_name );
158 if (os->pzOptArg == NULL)
159 return;
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;
167 os->pzOptArg = NULL;
170 switch (type) {
171 case ENV_IMM:
173 * Process only immediate actions
175 if (DO_IMMEDIATELY(os->flags))
176 break;
177 return;
179 case ENV_NON_IMM:
181 * Process only NON immediate actions
183 if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
184 break;
185 return;
187 default: /* process everything */
188 break;
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) {
199 os->pzOptArg = NULL;
200 } else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL)
201 && (*os->pzOptArg == NUL)) {
202 os->pzOptArg = NULL;
203 } else if (*os->pzOptArg == NUL) {
204 os->pzOptArg = zNil;
205 } else {
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....
218 LOCAL void
219 doEnvPresets( tOptions* pOpts, teEnvPresetType type )
221 int ct;
222 tOptState st;
223 char* pzFlagName;
224 size_t spaceLeft;
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)
232 return;
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) )
249 continue;
252 * IF there is no such environment variable,
253 * THEN skip this entry, too.
255 if (strlen( st.pOD->pz_NAME ) >= spaceLeft)
256 continue;
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);
276 * Local Variables:
277 * mode: C
278 * c-file-style: "stroustrup"
279 * indent-tabs-mode: nil
280 * End:
281 * end of autoopts/environment.c */