environment.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. * $Id: environment.c,v 4.17 2008/06/14 22:24:22 bkorb Exp $
  3. * Time-stamp: "2007-07-04 11:33:50 bkorb"
  4. *
  5. * This file contains all of the routines that must be linked into
  6. * an executable to use the generated option processing. The optional
  7. * routines are in separately compiled modules so that they will not
  8. * necessarily be linked in.
  9. *
  10. * This file is part of AutoOpts, a companion to AutoGen.
  11. * AutoOpts is free software.
  12. * AutoOpts is copyright (c) 1992-2008 by Bruce Korb - all rights reserved
  13. * AutoOpts is copyright (c) 1992-2008 by Bruce Korb - all rights reserved
  14. *
  15. * AutoOpts is available under any one of two licenses. The license
  16. * in use must be one of these two and the choice is under the control
  17. * of the user of the license.
  18. *
  19. * The GNU Lesser General Public License, version 3 or later
  20. * See the files "COPYING.lgplv3" and "COPYING.gplv3"
  21. *
  22. * The Modified Berkeley Software Distribution License
  23. * See the file "COPYING.mbsd"
  24. *
  25. * These files have the following md5sums:
  26. *
  27. * 239588c55c22c60ffe159946a760a33e pkg/libopts/COPYING.gplv3
  28. * fa82ca978890795162346e661b47161a pkg/libopts/COPYING.lgplv3
  29. * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
  30. */
  31. /* = = = START-STATIC-FORWARD = = = */
  32. /* static forward declarations maintained by mk-fwd */
  33. static void
  34. checkEnvOpt(tOptState * os, char * env_name,
  35. tOptions* pOpts, teEnvPresetType type);
  36. /* = = = END-STATIC-FORWARD = = = */
  37. /*
  38. * doPrognameEnv - check for preset values from the ${PROGNAME}
  39. * environment variable. This is accomplished by parsing the text into
  40. * tokens, temporarily replacing the arg vector and calling
  41. * doImmediateOpts and/or doRegularOpts.
  42. */
  43. LOCAL void
  44. doPrognameEnv( tOptions* pOpts, teEnvPresetType type )
  45. {
  46. char const* pczOptStr = getenv( pOpts->pzPROGNAME );
  47. token_list_t* pTL;
  48. int sv_argc;
  49. tAoUI sv_flag;
  50. char** sv_argv;
  51. /*
  52. * IF there is no such environment variable
  53. * *or* there is, but we are doing immediate opts and there are
  54. * no immediate opts to do (--help inside $PROGNAME is silly,
  55. * but --no-load-defs is not, so that is marked)
  56. * THEN bail out now. (
  57. */
  58. if ( (pczOptStr == NULL)
  59. || ( (type == ENV_IMM)
  60. && ((pOpts->fOptSet & OPTPROC_HAS_IMMED) == 0) ) )
  61. return;
  62. /*
  63. * Tokenize the string. If there's nothing of interest, we'll bail
  64. * here immediately.
  65. */
  66. pTL = ao_string_tokenize( pczOptStr );
  67. if (pTL == NULL)
  68. return;
  69. /*
  70. * Substitute our $PROGNAME argument list for the real one
  71. */
  72. sv_argc = pOpts->origArgCt;
  73. sv_argv = pOpts->origArgVect;
  74. sv_flag = pOpts->fOptSet;
  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. pOpts->curOptIdx = 1;
  85. pOpts->pzCurOpt = NULL;
  86. switch (type) {
  87. case ENV_IMM:
  88. /*
  89. * We know the OPTPROC_HAS_IMMED bit is set.
  90. */
  91. (void)doImmediateOpts( pOpts );
  92. break;
  93. case ENV_NON_IMM:
  94. (void)doRegularOpts( pOpts );
  95. break;
  96. default:
  97. /*
  98. * Only to immediate opts if the OPTPROC_HAS_IMMED bit is set.
  99. */
  100. if (pOpts->fOptSet & OPTPROC_HAS_IMMED) {
  101. (void)doImmediateOpts( pOpts );
  102. pOpts->curOptIdx = 1;
  103. pOpts->pzCurOpt = NULL;
  104. }
  105. (void)doRegularOpts( pOpts );
  106. break;
  107. }
  108. /*
  109. * Free up the temporary arg vector and restore the original program args.
  110. */
  111. free( pTL );
  112. pOpts->origArgVect = sv_argv;
  113. pOpts->origArgCt = sv_argc;
  114. pOpts->fOptSet = sv_flag;
  115. }
  116. static void
  117. checkEnvOpt(tOptState * os, char * env_name,
  118. tOptions* pOpts, teEnvPresetType type)
  119. {
  120. os->pzOptArg = getenv( env_name );
  121. if (os->pzOptArg == NULL)
  122. return;
  123. os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
  124. os->optType = TOPT_UNDEFINED;
  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. switch (type) {
  131. case ENV_IMM:
  132. /*
  133. * Process only immediate actions
  134. */
  135. if (DO_IMMEDIATELY(os->flags))
  136. break;
  137. return;
  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. default: /* process everything */
  146. break;
  147. }
  148. /*
  149. * Make sure the option value string is persistent and consistent.
  150. *
  151. * The interpretation of the option value depends
  152. * on the type of value argument the option takes
  153. */
  154. if (os->pzOptArg != NULL) {
  155. if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
  156. os->pzOptArg = NULL;
  157. } else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL)
  158. && (*os->pzOptArg == NUL)) {
  159. os->pzOptArg = NULL;
  160. } else if (*os->pzOptArg == NUL) {
  161. os->pzOptArg = zNil;
  162. } else {
  163. AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" );
  164. os->flags |= OPTST_ALLOC_ARG;
  165. }
  166. }
  167. handleOption( pOpts, os );
  168. }
  169. /*
  170. * doEnvPresets - check for preset values from the envrionment
  171. * This routine should process in all, immediate or normal modes....
  172. */
  173. LOCAL void
  174. doEnvPresets( tOptions* pOpts, teEnvPresetType type )
  175. {
  176. int ct;
  177. tOptState st;
  178. char* pzFlagName;
  179. size_t spaceLeft;
  180. char zEnvName[ AO_NAME_SIZE ];
  181. /*
  182. * Finally, see if we are to look at the environment
  183. * variables for initial values.
  184. */
  185. if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
  186. return;
  187. doPrognameEnv( pOpts, type );
  188. ct = pOpts->presetOptCt;
  189. st.pOD = pOpts->pOptDesc;
  190. pzFlagName = zEnvName
  191. + snprintf( zEnvName, sizeof( zEnvName ), "%s_", pOpts->pzPROGNAME );
  192. spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1;
  193. for (;ct-- > 0; st.pOD++) {
  194. /*
  195. * If presetting is disallowed, then skip this entry
  196. */
  197. if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
  198. || (st.pOD->optEquivIndex != NO_EQUIVALENT) )
  199. continue;
  200. /*
  201. * IF there is no such environment variable,
  202. * THEN skip this entry, too.
  203. */
  204. if (strlen( st.pOD->pz_NAME ) >= spaceLeft)
  205. continue;
  206. /*
  207. * Set up the option state
  208. */
  209. strcpy( pzFlagName, st.pOD->pz_NAME );
  210. checkEnvOpt(&st, zEnvName, pOpts, type);
  211. }
  212. /*
  213. * Special handling for ${PROGNAME_LOAD_OPTS}
  214. */
  215. if (pOpts->specOptIdx.save_opts != 0) {
  216. st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
  217. strcpy( pzFlagName, st.pOD->pz_NAME );
  218. checkEnvOpt(&st, zEnvName, pOpts, type);
  219. }
  220. }
  221. /*
  222. * Local Variables:
  223. * mode: C
  224. * c-file-style: "stroustrup"
  225. * indent-tabs-mode: nil
  226. * End:
  227. * end of autoopts/environment.c */