Deleted Added
full compact
init.c (285169) init.c (294554)
1/**
2 * \file initialize.c
3 *
4 * initialize the libopts data structures.
5 *
6 * @addtogroup autoopts
7 * @{
8 */
9/*
10 * This file is part of AutoOpts, a companion to AutoGen.
11 * AutoOpts is free software.
12 * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
13 *
14 * AutoOpts is available under any one of two licenses. The license
15 * in use must be one of these two and the choice is under the control
16 * of the user of the license.
17 *
18 * The GNU Lesser General Public License, version 3 or later
19 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
20 *
21 * The Modified Berkeley Software Distribution License
22 * See the file "COPYING.mbsd"
23 *
24 * These files have the following sha256 sums:
25 *
26 * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
27 * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
28 * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
29 */
30
31/* = = = START-STATIC-FORWARD = = = */
32static tSuccess
33do_presets(tOptions * opts);
34/* = = = END-STATIC-FORWARD = = = */
35
36/**
37 * Make sure the option descriptor is there and that we understand it.
38 * This should be called from any user entry point where one needs to
39 * worry about validity. (Some entry points are free to assume that
40 * the call is not the first to the library and, thus, that this has
41 * already been called.)
42 *
43 * Upon successful completion, pzProgName and pzProgPath are set.
44 *
45 * @param[in,out] opts program options descriptor
46 * @param[in] pname name of program, from argv[]
47 * @returns SUCCESS or FAILURE
48 */
49LOCAL tSuccess
50validate_struct(tOptions * opts, char const * pname)
51{
52 if (opts == NULL) {
53 fputs(zno_opt_arg, stderr);
54 return FAILURE;
55 }
56 print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0);
57
58 /*
59 * IF the client has enabled translation and the translation procedure
60 * is available, then go do it.
61 */
62 if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
63 && (opts->pTransProc != NULL)
64 && (option_xlateable_txt.field_ct != 0) ) {
65 /*
66 * If option names are not to be translated at all, then do not do
67 * it for configuration parsing either. (That is the bit that really
68 * gets tested anyway.)
69 */
70 if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT)
71 opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG;
72 opts->pTransProc();
73 }
74
75 /*
76 * IF the struct version is not the current, and also
77 * either too large (?!) or too small,
78 * THEN emit error message and fail-exit
79 */
80 if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION )
81 && ( (opts->structVersion > OPTIONS_STRUCT_VERSION )
82 || (opts->structVersion < OPTIONS_MINIMUM_VERSION )
83 ) ) {
84 fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion));
85 if (opts->structVersion > OPTIONS_STRUCT_VERSION )
86 fputs(ztoo_new, stderr);
87 else
88 fputs(ztoo_old, stderr);
89
90 fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr);
91 return FAILURE;
92 }
93
94 /*
95 * If the program name hasn't been set, then set the name and the path
96 * and the set of equivalent characters.
97 */
98 if (opts->pzProgName == NULL) {
99 char const * pz = strrchr(pname, DIRCH);
1/**
2 * \file initialize.c
3 *
4 * initialize the libopts data structures.
5 *
6 * @addtogroup autoopts
7 * @{
8 */
9/*
10 * This file is part of AutoOpts, a companion to AutoGen.
11 * AutoOpts is free software.
12 * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
13 *
14 * AutoOpts is available under any one of two licenses. The license
15 * in use must be one of these two and the choice is under the control
16 * of the user of the license.
17 *
18 * The GNU Lesser General Public License, version 3 or later
19 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
20 *
21 * The Modified Berkeley Software Distribution License
22 * See the file "COPYING.mbsd"
23 *
24 * These files have the following sha256 sums:
25 *
26 * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
27 * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
28 * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
29 */
30
31/* = = = START-STATIC-FORWARD = = = */
32static tSuccess
33do_presets(tOptions * opts);
34/* = = = END-STATIC-FORWARD = = = */
35
36/**
37 * Make sure the option descriptor is there and that we understand it.
38 * This should be called from any user entry point where one needs to
39 * worry about validity. (Some entry points are free to assume that
40 * the call is not the first to the library and, thus, that this has
41 * already been called.)
42 *
43 * Upon successful completion, pzProgName and pzProgPath are set.
44 *
45 * @param[in,out] opts program options descriptor
46 * @param[in] pname name of program, from argv[]
47 * @returns SUCCESS or FAILURE
48 */
49LOCAL tSuccess
50validate_struct(tOptions * opts, char const * pname)
51{
52 if (opts == NULL) {
53 fputs(zno_opt_arg, stderr);
54 return FAILURE;
55 }
56 print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0);
57
58 /*
59 * IF the client has enabled translation and the translation procedure
60 * is available, then go do it.
61 */
62 if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
63 && (opts->pTransProc != NULL)
64 && (option_xlateable_txt.field_ct != 0) ) {
65 /*
66 * If option names are not to be translated at all, then do not do
67 * it for configuration parsing either. (That is the bit that really
68 * gets tested anyway.)
69 */
70 if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT)
71 opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG;
72 opts->pTransProc();
73 }
74
75 /*
76 * IF the struct version is not the current, and also
77 * either too large (?!) or too small,
78 * THEN emit error message and fail-exit
79 */
80 if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION )
81 && ( (opts->structVersion > OPTIONS_STRUCT_VERSION )
82 || (opts->structVersion < OPTIONS_MINIMUM_VERSION )
83 ) ) {
84 fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion));
85 if (opts->structVersion > OPTIONS_STRUCT_VERSION )
86 fputs(ztoo_new, stderr);
87 else
88 fputs(ztoo_old, stderr);
89
90 fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr);
91 return FAILURE;
92 }
93
94 /*
95 * If the program name hasn't been set, then set the name and the path
96 * and the set of equivalent characters.
97 */
98 if (opts->pzProgName == NULL) {
99 char const * pz = strrchr(pname, DIRCH);
100 char const ** pp =
101 (char const **)(void **)&(opts->pzProgName);
100 char const ** pp = VOIDP(&(opts->pzProgName));
102
103 if (pz != NULL)
104 *pp = pz+1;
105 else
106 *pp = pname;
107
101
102 if (pz != NULL)
103 *pp = pz+1;
104 else
105 *pp = pname;
106
108 pz = pathfind(getenv("PATH"), (char *)pname, "rx");
107 pz = pathfind(getenv("PATH"), pname, "rx");
109 if (pz != NULL)
110 pname = VOIDP(pz);
111
112 pp = (char const **)VOIDP(&(opts->pzProgPath));
113 *pp = pname;
114
115 /*
116 * when comparing long names, these are equivalent
117 */
118 strequate(zSepChars);
119 }
120
121 return SUCCESS;
122}
123
124/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
125 *
126 * DO PRESETS
127 *
128 * The next several routines do the immediate action pass on the command
129 * line options, then the environment variables, then the config files in
130 * reverse order. Once done with that, the order is reversed and all
131 * the config files and environment variables are processed again, this
132 * time only processing the non-immediate action options. do_presets()
133 * will then return for optionProcess() to do the final pass on the command
134 * line arguments.
135 */
136
137/**
138 * scan the command line for immediate action options.
139 * This is only called the first time through.
140 * While this procedure is active, the OPTPROC_IMMEDIATE is true.
141 *
142 * @param pOpts program options descriptor
143 * @returns SUCCESS or FAILURE
144 */
145LOCAL tSuccess
146immediate_opts(tOptions * opts)
147{
148 tSuccess res;
149
150 opts->fOptSet |= OPTPROC_IMMEDIATE;
151 opts->curOptIdx = 1; /* start by skipping program name */
152 opts->pzCurOpt = NULL;
153
154 /*
155 * Examine all the options from the start. We process any options that
156 * are marked for immediate processing.
157 */
158 for (;;) {
159 tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
160
161 res = next_opt(opts, &opt_st);
162 switch (res) {
163 case FAILURE: goto failed_option;
164 case PROBLEM: res = SUCCESS; goto leave;
165 case SUCCESS: break;
166 }
167
168 /*
169 * IF this is an immediate-attribute option, then do it.
170 */
171 if (! DO_IMMEDIATELY(opt_st.flags))
172 continue;
173
174 if (! SUCCESSFUL(handle_opt(opts, &opt_st)))
175 break;
176 } failed_option:;
177
178 if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
179 (*opts->pUsageProc)(opts, EXIT_FAILURE);
180
181 leave:
182
183 opts->fOptSet &= ~OPTPROC_IMMEDIATE;
184 return res;
185}
186
187/**
188 * check for preset values from a config files or envrionment variables
189 *
190 * @param[in,out] opts the structure with the option names to check
191 */
192static tSuccess
193do_presets(tOptions * opts)
194{
195 tOptDesc * od = NULL;
196
197 if (! SUCCESSFUL(immediate_opts(opts)))
198 return FAILURE;
199
200 /*
201 * IF this option set has a --save-opts option, then it also
202 * has a --load-opts option. See if a command line option has disabled
203 * option presetting.
204 */
205 if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT)
206 && (opts->specOptIdx.save_opts != 0)) {
207 od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
208 if (DISABLED_OPT(od))
209 return SUCCESS;
210 }
211
212 /*
213 * Until we return from this procedure, disable non-presettable opts
214 */
215 opts->fOptSet |= OPTPROC_PRESETTING;
216 /*
217 * IF there are no config files,
218 * THEN do any environment presets and leave.
219 */
220 if (opts->papzHomeList == NULL) {
221 env_presets(opts, ENV_ALL);
222 }
223 else {
224 env_presets(opts, ENV_IMM);
225
226 /*
227 * Check to see if environment variables have disabled presetting.
228 */
229 if ((od != NULL) && ! DISABLED_OPT(od))
230 intern_file_load(opts);
231
232 /*
233 * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
234 * variable options. Only the loading of .rc files.
235 */
236 env_presets(opts, ENV_NON_IMM);
237 }
238 opts->fOptSet &= ~OPTPROC_PRESETTING;
239
240 return SUCCESS;
241}
242
243/**
244 * AutoOpts initialization
245 *
246 * @param[in,out] opts the structure to initialize
247 * @param[in] a_ct program argument count
248 * @param[in] a_v program argument vector
249 */
250LOCAL bool
251ao_initialize(tOptions * opts, int a_ct, char ** a_v)
252{
253 if ((opts->fOptSet & OPTPROC_INITDONE) != 0)
254 return true;
255
256 opts->origArgCt = (unsigned int)a_ct;
257 opts->origArgVect = a_v;
258 opts->fOptSet |= OPTPROC_INITDONE;
259
260 if (HAS_pzPkgDataDir(opts))
261 program_pkgdatadir = opts->pzPkgDataDir;
262
263 if (! SUCCESSFUL(do_presets(opts)))
264 return false;
265
266 /*
267 * IF option name conversion was suppressed but it is not suppressed
268 * for the command line, then it's time to translate option names.
269 * Usage text will not get retranslated.
270 */
271 if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
272 && (opts->pTransProc != NULL)
273 && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG)
274 ) {
275 opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
276 (*opts->pTransProc)();
277 }
278
279 if ((opts->fOptSet & OPTPROC_REORDER) != 0)
280 optionSort(opts);
281
282 opts->curOptIdx = 1;
283 opts->pzCurOpt = NULL;
284 return true;
285}
286
287/** @}
288 *
289 * Local Variables:
290 * mode: C
291 * c-file-style: "stroustrup"
292 * indent-tabs-mode: nil
293 * End:
294 * end of autoopts/initialize.c */
108 if (pz != NULL)
109 pname = VOIDP(pz);
110
111 pp = (char const **)VOIDP(&(opts->pzProgPath));
112 *pp = pname;
113
114 /*
115 * when comparing long names, these are equivalent
116 */
117 strequate(zSepChars);
118 }
119
120 return SUCCESS;
121}
122
123/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
124 *
125 * DO PRESETS
126 *
127 * The next several routines do the immediate action pass on the command
128 * line options, then the environment variables, then the config files in
129 * reverse order. Once done with that, the order is reversed and all
130 * the config files and environment variables are processed again, this
131 * time only processing the non-immediate action options. do_presets()
132 * will then return for optionProcess() to do the final pass on the command
133 * line arguments.
134 */
135
136/**
137 * scan the command line for immediate action options.
138 * This is only called the first time through.
139 * While this procedure is active, the OPTPROC_IMMEDIATE is true.
140 *
141 * @param pOpts program options descriptor
142 * @returns SUCCESS or FAILURE
143 */
144LOCAL tSuccess
145immediate_opts(tOptions * opts)
146{
147 tSuccess res;
148
149 opts->fOptSet |= OPTPROC_IMMEDIATE;
150 opts->curOptIdx = 1; /* start by skipping program name */
151 opts->pzCurOpt = NULL;
152
153 /*
154 * Examine all the options from the start. We process any options that
155 * are marked for immediate processing.
156 */
157 for (;;) {
158 tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
159
160 res = next_opt(opts, &opt_st);
161 switch (res) {
162 case FAILURE: goto failed_option;
163 case PROBLEM: res = SUCCESS; goto leave;
164 case SUCCESS: break;
165 }
166
167 /*
168 * IF this is an immediate-attribute option, then do it.
169 */
170 if (! DO_IMMEDIATELY(opt_st.flags))
171 continue;
172
173 if (! SUCCESSFUL(handle_opt(opts, &opt_st)))
174 break;
175 } failed_option:;
176
177 if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
178 (*opts->pUsageProc)(opts, EXIT_FAILURE);
179
180 leave:
181
182 opts->fOptSet &= ~OPTPROC_IMMEDIATE;
183 return res;
184}
185
186/**
187 * check for preset values from a config files or envrionment variables
188 *
189 * @param[in,out] opts the structure with the option names to check
190 */
191static tSuccess
192do_presets(tOptions * opts)
193{
194 tOptDesc * od = NULL;
195
196 if (! SUCCESSFUL(immediate_opts(opts)))
197 return FAILURE;
198
199 /*
200 * IF this option set has a --save-opts option, then it also
201 * has a --load-opts option. See if a command line option has disabled
202 * option presetting.
203 */
204 if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT)
205 && (opts->specOptIdx.save_opts != 0)) {
206 od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
207 if (DISABLED_OPT(od))
208 return SUCCESS;
209 }
210
211 /*
212 * Until we return from this procedure, disable non-presettable opts
213 */
214 opts->fOptSet |= OPTPROC_PRESETTING;
215 /*
216 * IF there are no config files,
217 * THEN do any environment presets and leave.
218 */
219 if (opts->papzHomeList == NULL) {
220 env_presets(opts, ENV_ALL);
221 }
222 else {
223 env_presets(opts, ENV_IMM);
224
225 /*
226 * Check to see if environment variables have disabled presetting.
227 */
228 if ((od != NULL) && ! DISABLED_OPT(od))
229 intern_file_load(opts);
230
231 /*
232 * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
233 * variable options. Only the loading of .rc files.
234 */
235 env_presets(opts, ENV_NON_IMM);
236 }
237 opts->fOptSet &= ~OPTPROC_PRESETTING;
238
239 return SUCCESS;
240}
241
242/**
243 * AutoOpts initialization
244 *
245 * @param[in,out] opts the structure to initialize
246 * @param[in] a_ct program argument count
247 * @param[in] a_v program argument vector
248 */
249LOCAL bool
250ao_initialize(tOptions * opts, int a_ct, char ** a_v)
251{
252 if ((opts->fOptSet & OPTPROC_INITDONE) != 0)
253 return true;
254
255 opts->origArgCt = (unsigned int)a_ct;
256 opts->origArgVect = a_v;
257 opts->fOptSet |= OPTPROC_INITDONE;
258
259 if (HAS_pzPkgDataDir(opts))
260 program_pkgdatadir = opts->pzPkgDataDir;
261
262 if (! SUCCESSFUL(do_presets(opts)))
263 return false;
264
265 /*
266 * IF option name conversion was suppressed but it is not suppressed
267 * for the command line, then it's time to translate option names.
268 * Usage text will not get retranslated.
269 */
270 if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
271 && (opts->pTransProc != NULL)
272 && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG)
273 ) {
274 opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
275 (*opts->pTransProc)();
276 }
277
278 if ((opts->fOptSet & OPTPROC_REORDER) != 0)
279 optionSort(opts);
280
281 opts->curOptIdx = 1;
282 opts->pzCurOpt = NULL;
283 return true;
284}
285
286/** @}
287 *
288 * Local Variables:
289 * mode: C
290 * c-file-style: "stroustrup"
291 * indent-tabs-mode: nil
292 * End:
293 * end of autoopts/initialize.c */