environment.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * $Id: environment.c,v 4.21 2009/08/01 17:43:06 bkorb Exp $
  3. * Time-stamp: "2009-07-20 20:12:24 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-2009 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. * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
  27. * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
  28. * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
  29. */
  30. /* = = = START-STATIC-FORWARD = = = */
  31. /* static forward declarations maintained by mk-fwd */
  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. * No such beast? Then bail now.
  52. */
  53. if (pczOptStr == NULL)
  54. return;
  55. /*
  56. * Tokenize the string. If there's nothing of interest, we'll bail
  57. * here immediately.
  58. */
  59. pTL = ao_string_tokenize( pczOptStr );
  60. if (pTL == NULL)
  61. return;
  62. /*
  63. * Substitute our $PROGNAME argument list for the real one
  64. */
  65. sv_argc = pOpts->origArgCt;
  66. sv_argv = pOpts->origArgVect;
  67. sv_flag = pOpts->fOptSet;
  68. /*
  69. * We add a bogus pointer to the start of the list. The program name
  70. * has already been pulled from "argv", so it won't get dereferenced.
  71. * The option scanning code will skip the "program name" at the start
  72. * of this list of tokens, so we accommodate this way ....
  73. */
  74. pOpts->origArgVect = (char**)(pTL->tkn_list - 1);
  75. pOpts->origArgCt = pTL->tkn_ct + 1;
  76. pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
  77. pOpts->curOptIdx = 1;
  78. pOpts->pzCurOpt = NULL;
  79. switch (type) {
  80. case ENV_IMM:
  81. (void)doImmediateOpts( pOpts );
  82. break;
  83. case ENV_ALL:
  84. (void)doImmediateOpts( pOpts );
  85. pOpts->curOptIdx = 1;
  86. pOpts->pzCurOpt = NULL;
  87. /* FALLTHROUGH */
  88. case ENV_NON_IMM:
  89. (void)doRegularOpts( pOpts );
  90. }
  91. /*
  92. * Free up the temporary arg vector and restore the original program args.
  93. */
  94. free( pTL );
  95. pOpts->origArgVect = sv_argv;
  96. pOpts->origArgCt = sv_argc;
  97. pOpts->fOptSet = sv_flag;
  98. }
  99. static void
  100. checkEnvOpt(tOptState * os, char * env_name,
  101. tOptions* pOpts, teEnvPresetType type)
  102. {
  103. os->pzOptArg = getenv( env_name );
  104. if (os->pzOptArg == NULL)
  105. return;
  106. os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
  107. os->optType = TOPT_UNDEFINED;
  108. if ( (os->pOD->pz_DisablePfx != NULL)
  109. && (streqvcmp( os->pzOptArg, os->pOD->pz_DisablePfx ) == 0)) {
  110. os->flags |= OPTST_DISABLED;
  111. os->pzOptArg = NULL;
  112. }
  113. switch (type) {
  114. case ENV_IMM:
  115. /*
  116. * Process only immediate actions
  117. */
  118. if (DO_IMMEDIATELY(os->flags))
  119. break;
  120. return;
  121. case ENV_NON_IMM:
  122. /*
  123. * Process only NON immediate actions
  124. */
  125. if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
  126. break;
  127. return;
  128. default: /* process everything */
  129. break;
  130. }
  131. /*
  132. * Make sure the option value string is persistent and consistent.
  133. *
  134. * The interpretation of the option value depends
  135. * on the type of value argument the option takes
  136. */
  137. if (os->pzOptArg != NULL) {
  138. if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
  139. os->pzOptArg = NULL;
  140. } else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL)
  141. && (*os->pzOptArg == NUL)) {
  142. os->pzOptArg = NULL;
  143. } else if (*os->pzOptArg == NUL) {
  144. os->pzOptArg = zNil;
  145. } else {
  146. AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" );
  147. os->flags |= OPTST_ALLOC_ARG;
  148. }
  149. }
  150. handleOption( pOpts, os );
  151. }
  152. /*
  153. * doEnvPresets - check for preset values from the envrionment
  154. * This routine should process in all, immediate or normal modes....
  155. */
  156. LOCAL void
  157. doEnvPresets( tOptions* pOpts, teEnvPresetType type )
  158. {
  159. int ct;
  160. tOptState st;
  161. char* pzFlagName;
  162. size_t spaceLeft;
  163. char zEnvName[ AO_NAME_SIZE ];
  164. /*
  165. * Finally, see if we are to look at the environment
  166. * variables for initial values.
  167. */
  168. if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
  169. return;
  170. doPrognameEnv( pOpts, type );
  171. ct = pOpts->presetOptCt;
  172. st.pOD = pOpts->pOptDesc;
  173. pzFlagName = zEnvName
  174. + snprintf( zEnvName, sizeof( zEnvName ), "%s_", pOpts->pzPROGNAME );
  175. spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1;
  176. for (;ct-- > 0; st.pOD++) {
  177. /*
  178. * If presetting is disallowed, then skip this entry
  179. */
  180. if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
  181. || (st.pOD->optEquivIndex != NO_EQUIVALENT) )
  182. continue;
  183. /*
  184. * IF there is no such environment variable,
  185. * THEN skip this entry, too.
  186. */
  187. if (strlen( st.pOD->pz_NAME ) >= spaceLeft)
  188. continue;
  189. /*
  190. * Set up the option state
  191. */
  192. strcpy( pzFlagName, st.pOD->pz_NAME );
  193. checkEnvOpt(&st, zEnvName, pOpts, type);
  194. }
  195. /*
  196. * Special handling for ${PROGNAME_LOAD_OPTS}
  197. */
  198. if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
  199. && (pOpts->specOptIdx.save_opts != 0)) {
  200. st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
  201. strcpy( pzFlagName, st.pOD->pz_NAME );
  202. checkEnvOpt(&st, zEnvName, pOpts, type);
  203. }
  204. }
  205. /*
  206. * Local Variables:
  207. * mode: C
  208. * c-file-style: "stroustrup"
  209. * indent-tabs-mode: nil
  210. * End:
  211. * end of autoopts/environment.c */