1:
2: /**
3: * \file environment.c
4: *
5: * Time-stamp: "2011-04-06 09:35:55 bkorb"
6: *
7: * This file contains all of the routines that must be linked into
8: * an executable to use the generated option processing. The optional
9: * routines are in separately compiled modules so that they will not
10: * necessarily be linked in.
11: *
12: * This file is part of AutoOpts, a companion to AutoGen.
13: * AutoOpts is free software.
14: * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
15: *
16: * AutoOpts is available under any one of two licenses. The license
17: * in use must be one of these two and the choice is under the control
18: * of the user of the license.
19: *
20: * The GNU Lesser General Public License, version 3 or later
21: * See the files "COPYING.lgplv3" and "COPYING.gplv3"
22: *
23: * The Modified Berkeley Software Distribution License
24: * See the file "COPYING.mbsd"
25: *
26: * These files have the following md5sums:
27: *
28: * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
29: * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
30: * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
31: */
32:
33: /* = = = START-STATIC-FORWARD = = = */
34: static void
35: do_env_opt(tOptState * os, char * env_name,
36: tOptions* pOpts, teEnvPresetType type);
37: /* = = = END-STATIC-FORWARD = = = */
38:
39: /*
40: * doPrognameEnv - check for preset values from the ${PROGNAME}
41: * environment variable. This is accomplished by parsing the text into
42: * tokens, temporarily replacing the arg vector and calling
43: * doImmediateOpts and/or doRegularOpts.
44: */
45: LOCAL void
46: doPrognameEnv(tOptions* pOpts, teEnvPresetType type)
47: {
48: char const* pczOptStr = getenv(pOpts->pzPROGNAME);
49: token_list_t* pTL;
50: int sv_argc;
51: tAoUI sv_flag;
52: char** sv_argv;
53:
54: /*
55: * No such beast? Then bail now.
56: */
57: if (pczOptStr == NULL)
58: return;
59:
60: /*
61: * Tokenize the string. If there's nothing of interest, we'll bail
62: * here immediately.
63: */
64: pTL = ao_string_tokenize(pczOptStr);
65: if (pTL == NULL)
66: return;
67:
68: /*
69: * Substitute our $PROGNAME argument list for the real one
70: */
71: sv_argc = pOpts->origArgCt;
72: sv_argv = pOpts->origArgVect;
73: sv_flag = pOpts->fOptSet;
74:
75: /*
76: * We add a bogus pointer to the start of the list. The program name
77: * has already been pulled from "argv", so it won't get dereferenced.
78: * The option scanning code will skip the "program name" at the start
79: * of this list of tokens, so we accommodate this way ....
80: */
81: pOpts->origArgVect = (char**)(pTL->tkn_list - 1);
82: pOpts->origArgCt = pTL->tkn_ct + 1;
83: pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
84:
85: pOpts->curOptIdx = 1;
86: pOpts->pzCurOpt = NULL;
87:
88: switch (type) {
89: case ENV_IMM:
90: (void)doImmediateOpts(pOpts);
91: break;
92:
93: case ENV_ALL:
94: (void)doImmediateOpts(pOpts);
95: pOpts->curOptIdx = 1;
96: pOpts->pzCurOpt = NULL;
97: /* FALLTHROUGH */
98:
99: case ENV_NON_IMM:
100: (void)doRegularOpts(pOpts);
101: }
102:
103: /*
104: * Free up the temporary arg vector and restore the original program args.
105: */
106: free(pTL);
107: pOpts->origArgVect = sv_argv;
108: pOpts->origArgCt = sv_argc;
109: pOpts->fOptSet = sv_flag;
110: }
111:
112: static void
113: do_env_opt(tOptState * os, char * env_name,
114: tOptions* pOpts, teEnvPresetType type)
115: {
116: os->pzOptArg = getenv(env_name);
117: if (os->pzOptArg == NULL)
118: return;
119:
120: os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
121: os->optType = TOPT_UNDEFINED;
122:
123: if ( (os->pOD->pz_DisablePfx != NULL)
124: && (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) {
125: os->flags |= OPTST_DISABLED;
126: os->pzOptArg = NULL;
127: }
128:
129: switch (type) {
130: case ENV_IMM:
131: /*
132: * Process only immediate actions
133: */
134: if (DO_IMMEDIATELY(os->flags))
135: break;
136: return;
137:
138: case ENV_NON_IMM:
139: /*
140: * Process only NON immediate actions
141: */
142: if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
143: break;
144: return;
145:
146: default: /* process everything */
147: break;
148: }
149:
150: /*
151: * Make sure the option value string is persistent and consistent.
152: *
153: * The interpretation of the option value depends
154: * on the type of value argument the option takes
155: */
156: if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
157: /*
158: * Ignore any value.
159: */
160: os->pzOptArg = NULL;
161:
162: } else if (os->pzOptArg[0] == NUL) {
163: /*
164: * If the argument is the empty string and the argument is
165: * optional, then treat it as if the option was not specified.
166: */
167: if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0)
168: return;
169: os->pzOptArg = NULL;
170:
171: } else {
172: AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument");
173: os->flags |= OPTST_ALLOC_ARG;
174: }
175:
176: handle_opt(pOpts, os);
177: }
178:
179: /*
180: * doEnvPresets - check for preset values from the envrionment
181: * This routine should process in all, immediate or normal modes....
182: */
183: LOCAL void
184: doEnvPresets(tOptions* pOpts, teEnvPresetType type)
185: {
186: int ct;
187: tOptState st;
188: char* pzFlagName;
189: size_t spaceLeft;
190: char zEnvName[ AO_NAME_SIZE ];
191:
192: /*
193: * Finally, see if we are to look at the environment
194: * variables for initial values.
195: */
196: if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
197: return;
198:
199: doPrognameEnv(pOpts, type);
200:
201: ct = pOpts->presetOptCt;
202: st.pOD = pOpts->pOptDesc;
203:
204: pzFlagName = zEnvName
205: + snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME);
206: spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1;
207:
208: for (;ct-- > 0; st.pOD++) {
209: size_t nln;
210:
211: /*
212: * If presetting is disallowed, then skip this entry
213: */
214: if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
215: || (st.pOD->optEquivIndex != NO_EQUIVALENT) )
216: continue;
217:
218: /*
219: * IF there is no such environment variable,
220: * THEN skip this entry, too.
221: */
222: nln = strlen(st.pOD->pz_NAME) + 1;
223: if (nln <= spaceLeft) {
224: /*
225: * Set up the option state
226: */
227: memcpy(pzFlagName, st.pOD->pz_NAME, nln);
228: do_env_opt(&st, zEnvName, pOpts, type);
229: }
230: }
231:
232: /*
233: * Special handling for ${PROGNAME_LOAD_OPTS}
234: */
235: if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
236: && (pOpts->specOptIdx.save_opts != 0)) {
237: size_t nln;
238: st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
239:
240: if (st.pOD->pz_NAME == NULL)
241: return;
242:
243: nln = strlen(st.pOD->pz_NAME) + 1;
244:
245: if (nln > spaceLeft)
246: return;
247:
248: memcpy(pzFlagName, st.pOD->pz_NAME, nln);
249: do_env_opt(&st, zEnvName, pOpts, type);
250: }
251: }
252:
253: /*
254: * Local Variables:
255: * mode: C
256: * c-file-style: "stroustrup"
257: * indent-tabs-mode: nil
258: * End:
259: * end of autoopts/environment.c */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>