environment.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * $Id: environment.c,v 4.15 2007/07/04 21:36:37 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-2007 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 md5sums:
  25. *
  26. * 239588c55c22c60ffe159946a760a33e pkg/libopts/COPYING.gplv3
  27. * fa82ca978890795162346e661b47161a pkg/libopts/COPYING.lgplv3
  28. * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
  29. */
  30. /* = = = START-STATIC-FORWARD = = = */
  31. /* static forward declarations maintained by :mkfwd */
  32. static void
  33. checkEnvOpt(tOptState * os, char * env_name,
  34. tOptions* pOpts, teEnvPresetType type);
  35. /* = = = END-STATIC-FORWARD = = = */
  36. /*
  37. * doPrognameEnv - check for preset values from the ${PROGNAME}
  38. * environment variable. This is accomplished by parsing the text into
  39. * tokens, temporarily replacing the arg vector and calling
  40. * doImmediateOpts and/or doRegularOpts.
  41. */
  42. LOCAL void
  43. doPrognameEnv( tOptions* pOpts, teEnvPresetType type )
  44. {
  45. char const* pczOptStr = getenv( pOpts->pzPROGNAME );
  46. token_list_t* pTL;
  47. int sv_argc;
  48. tAoUI sv_flag;
  49. char** sv_argv;
  50. /*
  51. * IF there is no such environment variable
  52. * *or* there is, but we are doing immediate opts and there are
  53. * no immediate opts to do (--help inside $PROGNAME is silly,
  54. * but --no-load-defs is not, so that is marked)
  55. * THEN bail out now. (
  56. */
  57. if ( (pczOptStr == NULL)
  58. || ( (type == ENV_IMM)
  59. && ((pOpts->fOptSet & OPTPROC_HAS_IMMED) == 0) ) )
  60. return;
  61. /*
  62. * Tokenize the string. If there's nothing of interest, we'll bail
  63. * here immediately.
  64. */
  65. pTL = ao_string_tokenize( pczOptStr );
  66. if (pTL == NULL)
  67. return;
  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. * We add a bogus pointer to the start of the list. The program name
  76. * has already been pulled from "argv", so it won't get dereferenced.
  77. * The option scanning code will skip the "program name" at the start
  78. * of this list of tokens, so we accommodate this way ....
  79. */
  80. pOpts->origArgVect = (char**)(pTL->tkn_list - 1);
  81. pOpts->origArgCt = pTL->tkn_ct + 1;
  82. pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
  83. pOpts->curOptIdx = 1;
  84. pOpts->pzCurOpt = NULL;
  85. switch (type) {
  86. case ENV_IMM:
  87. /*
  88. * We know the OPTPROC_HAS_IMMED bit is set.
  89. */
  90. (void)doImmediateOpts( pOpts );
  91. break;
  92. case ENV_NON_IMM:
  93. (void)doRegularOpts( pOpts );
  94. break;
  95. default:
  96. /*
  97. * Only to immediate opts if the OPTPROC_HAS_IMMED bit is set.
  98. */
  99. if (pOpts->fOptSet & OPTPROC_HAS_IMMED) {
  100. (void)doImmediateOpts( pOpts );
  101. pOpts->curOptIdx = 1;
  102. pOpts->pzCurOpt = NULL;
  103. }
  104. (void)doRegularOpts( pOpts );
  105. break;
  106. }
  107. /*
  108. * Free up the temporary arg vector and restore the original program args.
  109. */
  110. free( pTL );
  111. pOpts->origArgVect = sv_argv;
  112. pOpts->origArgCt = sv_argc;
  113. pOpts->fOptSet = sv_flag;
  114. }
  115. static void
  116. checkEnvOpt(tOptState * os, char * env_name,
  117. tOptions* pOpts, teEnvPresetType type)
  118. {
  119. os->pzOptArg = getenv( env_name );
  120. if (os->pzOptArg == NULL)
  121. return;
  122. os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
  123. os->optType = TOPT_UNDEFINED;
  124. if ( (os->pOD->pz_DisablePfx != NULL)
  125. && (streqvcmp( os->pzOptArg, os->pOD->pz_DisablePfx ) == 0)) {
  126. os->flags |= OPTST_DISABLED;
  127. os->pzOptArg = NULL;
  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. case ENV_NON_IMM:
  138. /*
  139. * Process only NON immediate actions
  140. */
  141. if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
  142. break;
  143. return;
  144. default: /* process everything */
  145. break;
  146. }
  147. /*
  148. * Make sure the option value string is persistent and consistent.
  149. *
  150. * The interpretation of the option value depends
  151. * on the type of value argument the option takes
  152. */
  153. if (os->pzOptArg != NULL) {
  154. if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
  155. os->pzOptArg = NULL;
  156. } else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL)
  157. && (*os->pzOptArg == NUL)) {
  158. os->pzOptArg = NULL;
  159. } else if (*os->pzOptArg == NUL) {
  160. os->pzOptArg = zNil;
  161. } else {
  162. AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" );
  163. os->flags |= OPTST_ALLOC_ARG;
  164. }
  165. }
  166. handleOption( pOpts, os );
  167. }
  168. /*
  169. * doEnvPresets - check for preset values from the envrionment
  170. * This routine should process in all, immediate or normal modes....
  171. */
  172. LOCAL void
  173. doEnvPresets( tOptions* pOpts, teEnvPresetType type )
  174. {
  175. int ct;
  176. tOptState st;
  177. char* pzFlagName;
  178. size_t spaceLeft;
  179. char zEnvName[ AO_NAME_SIZE ];
  180. /*
  181. * Finally, see if we are to look at the environment
  182. * variables for initial values.
  183. */
  184. if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
  185. return;
  186. doPrognameEnv( pOpts, type );
  187. ct = pOpts->presetOptCt;
  188. st.pOD = pOpts->pOptDesc;
  189. pzFlagName = zEnvName
  190. + snprintf( zEnvName, sizeof( zEnvName ), "%s_", pOpts->pzPROGNAME );
  191. spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1;
  192. for (;ct-- > 0; st.pOD++) {
  193. /*
  194. * If presetting is disallowed, then skip this entry
  195. */
  196. if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
  197. || (st.pOD->optEquivIndex != NO_EQUIVALENT) )
  198. continue;
  199. /*
  200. * IF there is no such environment variable,
  201. * THEN skip this entry, too.
  202. */
  203. if (strlen( st.pOD->pz_NAME ) >= spaceLeft)
  204. continue;
  205. /*
  206. * Set up the option state
  207. */
  208. strcpy( pzFlagName, st.pOD->pz_NAME );
  209. checkEnvOpt(&st, zEnvName, pOpts, type);
  210. }
  211. /*
  212. * Special handling for ${PROGNAME_LOAD_OPTS}
  213. */
  214. if (pOpts->specOptIdx.save_opts != 0) {
  215. st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
  216. strcpy( pzFlagName, st.pOD->pz_NAME );
  217. checkEnvOpt(&st, zEnvName, pOpts, type);
  218. }
  219. }
  220. /*
  221. * Local Variables:
  222. * mode: C
  223. * c-file-style: "stroustrup"
  224. * indent-tabs-mode: nil
  225. * End:
  226. * end of autoopts/environment.c */