113978Smrkam/* $NetBSD$ */ 213978Smrkam 313978Smrkam 413978Smrkam/* 513978Smrkam * Id: 8700c8e91e8094c455392c691d9b6a7d62222240 613978Smrkam * Time-stamp: "2009-07-20 20:12:24 bkorb" 713978Smrkam * 813978Smrkam * This file contains all of the routines that must be linked into 913978Smrkam * an executable to use the generated option processing. The optional 1013978Smrkam * routines are in separately compiled modules so that they will not 1113978Smrkam * necessarily be linked in. 1213978Smrkam * 1313978Smrkam * This file is part of AutoOpts, a companion to AutoGen. 1413978Smrkam * AutoOpts is free software. 1513978Smrkam * AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved 1613978Smrkam * 1713978Smrkam * AutoOpts is available under any one of two licenses. The license 1813978Smrkam * in use must be one of these two and the choice is under the control 1913978Smrkam * of the user of the license. 2013978Smrkam * 2113978Smrkam * The GNU Lesser General Public License, version 3 or later 2213978Smrkam * See the files "COPYING.lgplv3" and "COPYING.gplv3" 2313978Smrkam * 2414305Smrkam * The Modified Berkeley Software Distribution License 2514305Smrkam * See the file "COPYING.mbsd" 2613978Smrkam * 2713978Smrkam * These files have the following md5sums: 2813978Smrkam * 2913978Smrkam * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 3013978Smrkam * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 3113978Smrkam * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd 3213978Smrkam */ 3313978Smrkam 3413978Smrkam/* = = = START-STATIC-FORWARD = = = */ 3513978Smrkam/* static forward declarations maintained by mk-fwd */ 3613978Smrkamstatic void 3714305SmrkamcheckEnvOpt(tOptState * os, char * env_name, 3813978Smrkam tOptions* pOpts, teEnvPresetType type); 3913978Smrkam/* = = = END-STATIC-FORWARD = = = */ 4013978Smrkam 4114801Sprr/* 4213978Smrkam * doPrognameEnv - check for preset values from the ${PROGNAME} 4313978Smrkam * environment variable. This is accomplished by parsing the text into 4413978Smrkam * tokens, temporarily replacing the arg vector and calling 4513978Smrkam * doImmediateOpts and/or doRegularOpts. 4613978Smrkam */ 4714305SmrkamLOCAL void 4813978SmrkamdoPrognameEnv( tOptions* pOpts, teEnvPresetType type ) 4914801Sprr{ 5014801Sprr char const* pczOptStr = getenv( pOpts->pzPROGNAME ); 5113978Smrkam token_list_t* pTL; 5213978Smrkam int sv_argc; 5313978Smrkam tAoUI sv_flag; 5413978Smrkam char** sv_argv; 5514305Smrkam 5613978Smrkam /* 5713978Smrkam * No such beast? Then bail now. 5813978Smrkam */ 5913978Smrkam if (pczOptStr == NULL) 6013978Smrkam return; 6113978Smrkam 6214305Smrkam /* 6313978Smrkam * Tokenize the string. If there's nothing of interest, we'll bail 6414305Smrkam * here immediately. 6513978Smrkam */ 6614305Smrkam pTL = ao_string_tokenize( pczOptStr ); 6714305Smrkam if (pTL == NULL) 6813978Smrkam return; 6914305Smrkam 7014305Smrkam /* 7114305Smrkam * Substitute our $PROGNAME argument list for the real one 7214305Smrkam */ 7313978Smrkam sv_argc = pOpts->origArgCt; 7413978Smrkam sv_argv = pOpts->origArgVect; 7513978Smrkam sv_flag = pOpts->fOptSet; 7613978Smrkam 7713978Smrkam /* 7813978Smrkam * We add a bogus pointer to the start of the list. The program name 7913978Smrkam * has already been pulled from "argv", so it won't get dereferenced. 8013978Smrkam * The option scanning code will skip the "program name" at the start 8113978Smrkam * of this list of tokens, so we accommodate this way .... 8213978Smrkam */ 8313978Smrkam pOpts->origArgVect = (char**)(pTL->tkn_list - 1); 8413978Smrkam pOpts->origArgCt = pTL->tkn_ct + 1; 8513978Smrkam pOpts->fOptSet &= ~OPTPROC_ERRSTOP; 8613978Smrkam 8713978Smrkam pOpts->curOptIdx = 1; 8813978Smrkam pOpts->pzCurOpt = NULL; 8913978Smrkam 9013978Smrkam switch (type) { 9113978Smrkam case ENV_IMM: 9213978Smrkam (void)doImmediateOpts( pOpts ); 9313978Smrkam break; 9413978Smrkam 9513978Smrkam case ENV_ALL: 9613978Smrkam (void)doImmediateOpts( pOpts ); 9713978Smrkam pOpts->curOptIdx = 1; 9813978Smrkam pOpts->pzCurOpt = NULL; 99 /* FALLTHROUGH */ 100 101 case ENV_NON_IMM: 102 (void)doRegularOpts( pOpts ); 103 } 104 105 /* 106 * Free up the temporary arg vector and restore the original program args. 107 */ 108 free( pTL ); 109 pOpts->origArgVect = sv_argv; 110 pOpts->origArgCt = sv_argc; 111 pOpts->fOptSet = sv_flag; 112} 113 114static void 115checkEnvOpt(tOptState * os, char * env_name, 116 tOptions* pOpts, teEnvPresetType type) 117{ 118 os->pzOptArg = getenv( env_name ); 119 if (os->pzOptArg == NULL) 120 return; 121 122 os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState; 123 os->optType = TOPT_UNDEFINED; 124 125 if ( (os->pOD->pz_DisablePfx != NULL) 126 && (streqvcmp( os->pzOptArg, os->pOD->pz_DisablePfx ) == 0)) { 127 os->flags |= OPTST_DISABLED; 128 os->pzOptArg = NULL; 129 } 130 131 switch (type) { 132 case ENV_IMM: 133 /* 134 * Process only immediate actions 135 */ 136 if (DO_IMMEDIATELY(os->flags)) 137 break; 138 return; 139 140 case ENV_NON_IMM: 141 /* 142 * Process only NON immediate actions 143 */ 144 if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags)) 145 break; 146 return; 147 148 default: /* process everything */ 149 break; 150 } 151 152 /* 153 * Make sure the option value string is persistent and consistent. 154 * 155 * The interpretation of the option value depends 156 * on the type of value argument the option takes 157 */ 158 if (os->pzOptArg != NULL) { 159 if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) { 160 os->pzOptArg = NULL; 161 } else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL) 162 && (*os->pzOptArg == NUL)) { 163 os->pzOptArg = NULL; 164 } else if (*os->pzOptArg == NUL) { 165 os->pzOptArg = zNil; 166 } else { 167 AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" ); 168 os->flags |= OPTST_ALLOC_ARG; 169 } 170 } 171 172 handleOption( pOpts, os ); 173} 174 175/* 176 * doEnvPresets - check for preset values from the envrionment 177 * This routine should process in all, immediate or normal modes.... 178 */ 179LOCAL void 180doEnvPresets( tOptions* pOpts, teEnvPresetType type ) 181{ 182 int ct; 183 tOptState st; 184 char* pzFlagName; 185 size_t spaceLeft; 186 char zEnvName[ AO_NAME_SIZE ]; 187 188 /* 189 * Finally, see if we are to look at the environment 190 * variables for initial values. 191 */ 192 if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0) 193 return; 194 195 doPrognameEnv( pOpts, type ); 196 197 ct = pOpts->presetOptCt; 198 st.pOD = pOpts->pOptDesc; 199 200 pzFlagName = zEnvName 201 + snprintf( zEnvName, sizeof( zEnvName ), "%s_", pOpts->pzPROGNAME ); 202 spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1; 203 204 for (;ct-- > 0; st.pOD++) { 205 /* 206 * If presetting is disallowed, then skip this entry 207 */ 208 if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0) 209 || (st.pOD->optEquivIndex != NO_EQUIVALENT) ) 210 continue; 211 212 /* 213 * IF there is no such environment variable, 214 * THEN skip this entry, too. 215 */ 216 if (strlen( st.pOD->pz_NAME ) >= spaceLeft) 217 continue; 218 219 /* 220 * Set up the option state 221 */ 222 strcpy( pzFlagName, st.pOD->pz_NAME ); 223 checkEnvOpt(&st, zEnvName, pOpts, type); 224 } 225 226 /* 227 * Special handling for ${PROGNAME_LOAD_OPTS} 228 */ 229 if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT) 230 && (pOpts->specOptIdx.save_opts != 0)) { 231 st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1; 232 strcpy( pzFlagName, st.pOD->pz_NAME ); 233 checkEnvOpt(&st, zEnvName, pOpts, type); 234 } 235} 236 237/* 238 * Local Variables: 239 * mode: C 240 * c-file-style: "stroustrup" 241 * indent-tabs-mode: nil 242 * End: 243 * end of autoopts/environment.c */ 244