environment.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * $Id: environment.c,v 4.8 2006/03/25 19:24:56 bkorb Exp $
  3. * Time-stamp: "2005-10-29 13:23:59 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. /*
  11. * Automated Options copyright 1992-2006 Bruce Korb
  12. *
  13. * Automated Options is free software.
  14. * You may redistribute it and/or modify it under the terms of the
  15. * GNU General Public License, as published by the Free Software
  16. * Foundation; either version 2, or (at your option) any later version.
  17. *
  18. * Automated Options is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with Automated Options. See the file "COPYING". If not,
  25. * write to: The Free Software Foundation, Inc.,
  26. * 51 Franklin Street, Fifth Floor,
  27. * Boston, MA 02110-1301, USA.
  28. *
  29. * As a special exception, Bruce Korb gives permission for additional
  30. * uses of the text contained in his release of AutoOpts.
  31. *
  32. * The exception is that, if you link the AutoOpts library with other
  33. * files to produce an executable, this does not by itself cause the
  34. * resulting executable to be covered by the GNU General Public License.
  35. * Your use of that executable is in no way restricted on account of
  36. * linking the AutoOpts library code into it.
  37. *
  38. * This exception does not however invalidate any other reasons why
  39. * the executable file might be covered by the GNU General Public License.
  40. *
  41. * This exception applies only to the code released by Bruce Korb under
  42. * the name AutoOpts. If you copy code from other sources under the
  43. * General Public License into a copy of AutoOpts, as the General Public
  44. * License permits, the exception does not apply to the code that you add
  45. * in this way. To avoid misleading anyone as to the status of such
  46. * modified files, you must delete this exception notice from them.
  47. *
  48. * If you write modifications of your own for AutoOpts, it is your choice
  49. * whether to permit this exception to apply to your modifications.
  50. * If you do not wish that, delete this exception notice.
  51. */
  52. /* = = = START-STATIC-FORWARD = = = */
  53. /* static forward declarations maintained by :mkfwd */
  54. /* = = = END-STATIC-FORWARD = = = */
  55. /*
  56. * doPrognameEnv - check for preset values from the ${PROGNAME}
  57. * environment variable. This is accomplished by parsing the text into
  58. * tokens, temporarily replacing the arg vector and calling
  59. * doImmediateOpts and/or doRegularOpts.
  60. */
  61. LOCAL void
  62. doPrognameEnv( tOptions* pOpts, teEnvPresetType type )
  63. {
  64. const char* pczOptStr = getenv( pOpts->pzPROGNAME );
  65. token_list_t* pTL;
  66. int sv_argc;
  67. tAoUI sv_flag;
  68. char** sv_argv;
  69. /*
  70. * IF there is no such environment variable
  71. * *or* there is, but we are doing immediate opts and there are
  72. * no immediate opts to do (--help inside $PROGNAME is silly,
  73. * but --no-load-defs is not, so that is marked)
  74. * THEN bail out now. (
  75. */
  76. if ( (pczOptStr == NULL)
  77. || ( (type == ENV_IMM)
  78. && ((pOpts->fOptSet & OPTPROC_HAS_IMMED) == 0) ) )
  79. return;
  80. /*
  81. * Tokenize the string. If there's nothing of interest, we'll bail
  82. * here immediately.
  83. */
  84. pTL = ao_string_tokenize( pczOptStr );
  85. if (pTL == NULL)
  86. return;
  87. /*
  88. * Substitute our $PROGNAME argument list for the real one
  89. */
  90. sv_argc = pOpts->origArgCt;
  91. sv_argv = pOpts->origArgVect;
  92. sv_flag = pOpts->fOptSet;
  93. /*
  94. * We add a bogus pointer to the start of the list. The program name
  95. * has already been pulled from "argv", so it won't get dereferenced.
  96. * The option scanning code will skip the "program name" at the start
  97. * of this list of tokens, so we accommodate this way ....
  98. */
  99. pOpts->origArgVect = (char**)(pTL->tkn_list - 1);
  100. pOpts->origArgCt = pTL->tkn_ct + 1;
  101. pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
  102. pOpts->curOptIdx = 1;
  103. pOpts->pzCurOpt = NULL;
  104. switch (type) {
  105. case ENV_IMM:
  106. /*
  107. * We know the OPTPROC_HAS_IMMED bit is set.
  108. */
  109. (void)doImmediateOpts( pOpts );
  110. break;
  111. case ENV_NON_IMM:
  112. (void)doRegularOpts( pOpts );
  113. break;
  114. default:
  115. /*
  116. * Only to immediate opts if the OPTPROC_HAS_IMMED bit is set.
  117. */
  118. if (pOpts->fOptSet & OPTPROC_HAS_IMMED) {
  119. (void)doImmediateOpts( pOpts );
  120. pOpts->curOptIdx = 1;
  121. pOpts->pzCurOpt = NULL;
  122. }
  123. (void)doRegularOpts( pOpts );
  124. break;
  125. }
  126. /*
  127. * Free up the temporary arg vector and restore the original program args.
  128. */
  129. free( pTL );
  130. pOpts->origArgVect = sv_argv;
  131. pOpts->origArgCt = sv_argc;
  132. pOpts->fOptSet = sv_flag;
  133. }
  134. /*
  135. * doEnvPresets - check for preset values from the envrionment
  136. * This routine should process in all, immediate or normal modes....
  137. */
  138. LOCAL void
  139. doEnvPresets( tOptions* pOpts, teEnvPresetType type )
  140. {
  141. int ct;
  142. tOptState st;
  143. char* pzFlagName;
  144. size_t spaceLeft;
  145. char zEnvName[ AO_NAME_SIZE ];
  146. /*
  147. * Finally, see if we are to look at the environment
  148. * variables for initial values.
  149. */
  150. if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
  151. return;
  152. doPrognameEnv( pOpts, type );
  153. ct = pOpts->presetOptCt;
  154. st.pOD = pOpts->pOptDesc;
  155. pzFlagName = zEnvName
  156. + snprintf( zEnvName, sizeof( zEnvName ), "%s_", pOpts->pzPROGNAME );
  157. spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1;
  158. for (;ct-- > 0; st.pOD++) {
  159. /*
  160. * If presetting is disallowed, then skip this entry
  161. */
  162. if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
  163. || (st.pOD->optEquivIndex != NO_EQUIVALENT) )
  164. continue;
  165. /*
  166. * IF there is no such environment variable,
  167. * THEN skip this entry, too.
  168. */
  169. if (strlen( st.pOD->pz_NAME ) >= spaceLeft)
  170. continue;
  171. /*
  172. * Set up the option state
  173. */
  174. strcpy( pzFlagName, st.pOD->pz_NAME );
  175. st.pzOptArg = getenv( zEnvName );
  176. if (st.pzOptArg == NULL)
  177. continue;
  178. st.flags = OPTST_PRESET | st.pOD->fOptState;
  179. st.optType = TOPT_UNDEFINED;
  180. if ( (st.pOD->pz_DisablePfx != NULL)
  181. && (streqvcmp( st.pzOptArg, st.pOD->pz_DisablePfx ) == 0)) {
  182. st.flags |= OPTST_DISABLED;
  183. st.pzOptArg = NULL;
  184. }
  185. switch (type) {
  186. case ENV_IMM:
  187. /*
  188. * Process only immediate actions
  189. */
  190. if (DO_IMMEDIATELY(st.flags))
  191. break;
  192. continue;
  193. case ENV_NON_IMM:
  194. /*
  195. * Process only NON immediate actions
  196. */
  197. if (DO_NORMALLY(st.flags) || DO_SECOND_TIME(st.flags))
  198. break;
  199. continue;
  200. default: /* process everything */
  201. break;
  202. }
  203. /*
  204. * Make sure the option value string is persistent and consistent.
  205. * This may be a memory leak, but we cannot do anything about it.
  206. *
  207. * The interpretation of the option value depends
  208. * on the type of value argument the option takes
  209. */
  210. if (st.pzOptArg != NULL) {
  211. if (OPTST_GET_ARGTYPE(st.pOD->fOptState) == OPARG_TYPE_NONE) {
  212. st.pzOptArg = NULL;
  213. } else if ( (st.pOD->fOptState & OPTST_ARG_OPTIONAL)
  214. && (*st.pzOptArg == NUL)) {
  215. st.pzOptArg = NULL;
  216. } else if (*st.pzOptArg == NUL) {
  217. st.pzOptArg = zNil;
  218. } else {
  219. AGDUPSTR( st.pzOptArg, st.pzOptArg, "option argument" );
  220. }
  221. }
  222. handleOption( pOpts, &st );
  223. }
  224. }
  225. /*
  226. * Local Variables:
  227. * mode: C
  228. * c-file-style: "stroustrup"
  229. * tab-width: 4
  230. * indent-tabs-mode: nil
  231. * End:
  232. * end of autoopts/environment.c */