init.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /**
  2. * \file initialize.c
  3. *
  4. * initialize the libopts data structures.
  5. *
  6. * @addtogroup autoopts
  7. * @{
  8. */
  9. /*
  10. * This file is part of AutoOpts, a companion to AutoGen.
  11. * AutoOpts is free software.
  12. * AutoOpts is Copyright (C) 1992-2014 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 sha256 sums:
  25. *
  26. * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
  27. * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
  28. * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
  29. */
  30. /* = = = START-STATIC-FORWARD = = = */
  31. static tSuccess
  32. do_presets(tOptions * opts);
  33. /* = = = END-STATIC-FORWARD = = = */
  34. /**
  35. * Make sure the option descriptor is there and that we understand it.
  36. * This should be called from any user entry point where one needs to
  37. * worry about validity. (Some entry points are free to assume that
  38. * the call is not the first to the library and, thus, that this has
  39. * already been called.)
  40. *
  41. * Upon successful completion, pzProgName and pzProgPath are set.
  42. *
  43. * @param[in,out] opts program options descriptor
  44. * @param[in] pname name of program, from argv[]
  45. * @returns SUCCESS or FAILURE
  46. */
  47. LOCAL tSuccess
  48. validate_struct(tOptions * opts, char const * pname)
  49. {
  50. if (opts == NULL) {
  51. fputs(zno_opt_arg, stderr);
  52. return FAILURE;
  53. }
  54. print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0);
  55. /*
  56. * IF the client has enabled translation and the translation procedure
  57. * is available, then go do it.
  58. */
  59. if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
  60. && (opts->pTransProc != NULL)
  61. && (option_xlateable_txt.field_ct != 0) ) {
  62. /*
  63. * If option names are not to be translated at all, then do not do
  64. * it for configuration parsing either. (That is the bit that really
  65. * gets tested anyway.)
  66. */
  67. if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT)
  68. opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG;
  69. (*opts->pTransProc)();
  70. }
  71. /*
  72. * IF the struct version is not the current, and also
  73. * either too large (?!) or too small,
  74. * THEN emit error message and fail-exit
  75. */
  76. if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION )
  77. && ( (opts->structVersion > OPTIONS_STRUCT_VERSION )
  78. || (opts->structVersion < OPTIONS_MINIMUM_VERSION )
  79. ) ) {
  80. static char const ao_ver_string[] =
  81. STR(AO_CURRENT)":"STR(AO_REVISION)":"STR(AO_AGE)"\n";
  82. fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion));
  83. if (opts->structVersion > OPTIONS_STRUCT_VERSION )
  84. fputs(ztoo_new, stderr);
  85. else
  86. fputs(ztoo_old, stderr);
  87. fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr);
  88. return FAILURE;
  89. }
  90. /*
  91. * If the program name hasn't been set, then set the name and the path
  92. * and the set of equivalent characters.
  93. */
  94. if (opts->pzProgName == NULL) {
  95. char const * pz = strrchr(pname, DIRCH);
  96. char const ** pp =
  97. (char const **)(void **)&(opts->pzProgName);
  98. if (pz != NULL)
  99. *pp = pz+1;
  100. else
  101. *pp = pname;
  102. pz = pathfind(getenv("PATH"), (char *)pname, "rx");
  103. if (pz != NULL)
  104. pname = (void *)pz;
  105. pp = (char const **)(void **)&(opts->pzProgPath);
  106. *pp = pname;
  107. /*
  108. * when comparing long names, these are equivalent
  109. */
  110. strequate(zSepChars);
  111. }
  112. return SUCCESS;
  113. }
  114. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  115. *
  116. * DO PRESETS
  117. *
  118. * The next several routines do the immediate action pass on the command
  119. * line options, then the environment variables, then the config files in
  120. * reverse order. Once done with that, the order is reversed and all
  121. * the config files and environment variables are processed again, this
  122. * time only processing the non-immediate action options. do_presets()
  123. * will then return for optionProcess() to do the final pass on the command
  124. * line arguments.
  125. */
  126. /**
  127. * scan the command line for immediate action options.
  128. * This is only called the first time through.
  129. * While this procedure is active, the OPTPROC_IMMEDIATE is true.
  130. *
  131. * @param pOpts program options descriptor
  132. * @returns SUCCESS or FAILURE
  133. */
  134. LOCAL tSuccess
  135. immediate_opts(tOptions * opts)
  136. {
  137. tSuccess res;
  138. opts->fOptSet |= OPTPROC_IMMEDIATE;
  139. opts->curOptIdx = 1; /* start by skipping program name */
  140. opts->pzCurOpt = NULL;
  141. /*
  142. * Examine all the options from the start. We process any options that
  143. * are marked for immediate processing.
  144. */
  145. for (;;) {
  146. tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
  147. res = next_opt(opts, &opt_st);
  148. switch (res) {
  149. case FAILURE: goto failed_option;
  150. case PROBLEM: res = SUCCESS; goto leave;
  151. case SUCCESS: break;
  152. }
  153. /*
  154. * IF this is an immediate-attribute option, then do it.
  155. */
  156. if (! DO_IMMEDIATELY(opt_st.flags))
  157. continue;
  158. if (! SUCCESSFUL(handle_opt(opts, &opt_st)))
  159. break;
  160. } failed_option:;
  161. if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
  162. (*opts->pUsageProc)(opts, EXIT_FAILURE);
  163. leave:
  164. opts->fOptSet &= ~OPTPROC_IMMEDIATE;
  165. return res;
  166. }
  167. /**
  168. * check for preset values from a config files or envrionment variables
  169. *
  170. * @param[in,out] opts the structure with the option names to check
  171. */
  172. static tSuccess
  173. do_presets(tOptions * opts)
  174. {
  175. tOptDesc * od = NULL;
  176. if (! SUCCESSFUL(immediate_opts(opts)))
  177. return FAILURE;
  178. /*
  179. * IF this option set has a --save-opts option, then it also
  180. * has a --load-opts option. See if a command line option has disabled
  181. * option presetting.
  182. */
  183. if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT)
  184. && (opts->specOptIdx.save_opts != 0)) {
  185. od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
  186. if (DISABLED_OPT(od))
  187. return SUCCESS;
  188. }
  189. /*
  190. * Until we return from this procedure, disable non-presettable opts
  191. */
  192. opts->fOptSet |= OPTPROC_PRESETTING;
  193. /*
  194. * IF there are no config files,
  195. * THEN do any environment presets and leave.
  196. */
  197. if (opts->papzHomeList == NULL) {
  198. env_presets(opts, ENV_ALL);
  199. }
  200. else {
  201. env_presets(opts, ENV_IMM);
  202. /*
  203. * Check to see if environment variables have disabled presetting.
  204. */
  205. if ((od != NULL) && ! DISABLED_OPT(od))
  206. intern_file_load(opts);
  207. /*
  208. * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
  209. * variable options. Only the loading of .rc files.
  210. */
  211. env_presets(opts, ENV_NON_IMM);
  212. }
  213. opts->fOptSet &= ~OPTPROC_PRESETTING;
  214. return SUCCESS;
  215. }
  216. /**
  217. * AutoOpts initialization
  218. *
  219. * @param[in,out] opts the structure to initialize
  220. * @param[in] a_ct program argument count
  221. * @param[in] a_v program argument vector
  222. */
  223. LOCAL bool
  224. ao_initialize(tOptions * opts, int a_ct, char ** a_v)
  225. {
  226. if ((opts->fOptSet & OPTPROC_INITDONE) != 0)
  227. return true;
  228. opts->origArgCt = (unsigned int)a_ct;
  229. opts->origArgVect = a_v;
  230. opts->fOptSet |= OPTPROC_INITDONE;
  231. if (HAS_pzPkgDataDir(opts))
  232. program_pkgdatadir = opts->pzPkgDataDir;
  233. if (! SUCCESSFUL(do_presets(opts)))
  234. return false;
  235. /*
  236. * IF option name conversion was suppressed but it is not suppressed
  237. * for the command line, then it's time to translate option names.
  238. * Usage text will not get retranslated.
  239. */
  240. if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
  241. && (opts->pTransProc != NULL)
  242. && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG)
  243. ) {
  244. opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
  245. (*opts->pTransProc)();
  246. }
  247. if ((opts->fOptSet & OPTPROC_REORDER) != 0)
  248. optionSort(opts);
  249. opts->curOptIdx = 1;
  250. opts->pzCurOpt = NULL;
  251. return true;
  252. }
  253. /** @}
  254. *
  255. * Local Variables:
  256. * mode: C
  257. * c-file-style: "stroustrup"
  258. * indent-tabs-mode: nil
  259. * End:
  260. * end of autoopts/initialize.c */