1
0

init.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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-2016 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. fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion));
  81. if (opts->structVersion > OPTIONS_STRUCT_VERSION )
  82. fputs(ztoo_new, stderr);
  83. else
  84. fputs(ztoo_old, stderr);
  85. fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr);
  86. return FAILURE;
  87. }
  88. /*
  89. * If the program name hasn't been set, then set the name and the path
  90. * and the set of equivalent characters.
  91. */
  92. if (opts->pzProgName == NULL) {
  93. char const * pz = strrchr(pname, DIRCH);
  94. char const ** pp =
  95. (char const **)(void **)&(opts->pzProgName);
  96. if (pz != NULL)
  97. *pp = pz+1;
  98. else
  99. *pp = pname;
  100. pz = pathfind(getenv("PATH"), (char *)pname, "rx");
  101. if (pz != NULL)
  102. pname = VOIDP(pz);
  103. pp = (char const **)VOIDP(&(opts->pzProgPath));
  104. *pp = pname;
  105. /*
  106. * when comparing long names, these are equivalent
  107. */
  108. strequate(zSepChars);
  109. }
  110. return SUCCESS;
  111. }
  112. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  113. *
  114. * DO PRESETS
  115. *
  116. * The next several routines do the immediate action pass on the command
  117. * line options, then the environment variables, then the config files in
  118. * reverse order. Once done with that, the order is reversed and all
  119. * the config files and environment variables are processed again, this
  120. * time only processing the non-immediate action options. do_presets()
  121. * will then return for optionProcess() to do the final pass on the command
  122. * line arguments.
  123. */
  124. /**
  125. * scan the command line for immediate action options.
  126. * This is only called the first time through.
  127. * While this procedure is active, the OPTPROC_IMMEDIATE is true.
  128. *
  129. * @param pOpts program options descriptor
  130. * @returns SUCCESS or FAILURE
  131. */
  132. LOCAL tSuccess
  133. immediate_opts(tOptions * opts)
  134. {
  135. tSuccess res;
  136. opts->fOptSet |= OPTPROC_IMMEDIATE;
  137. opts->curOptIdx = 1; /* start by skipping program name */
  138. opts->pzCurOpt = NULL;
  139. /*
  140. * Examine all the options from the start. We process any options that
  141. * are marked for immediate processing.
  142. */
  143. for (;;) {
  144. tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
  145. res = next_opt(opts, &opt_st);
  146. switch (res) {
  147. case FAILURE: goto failed_option;
  148. case PROBLEM: res = SUCCESS; goto leave;
  149. case SUCCESS: break;
  150. }
  151. /*
  152. * IF this is an immediate-attribute option, then do it.
  153. */
  154. if (! DO_IMMEDIATELY(opt_st.flags))
  155. continue;
  156. if (! SUCCESSFUL(handle_opt(opts, &opt_st)))
  157. break;
  158. } failed_option:;
  159. if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0)
  160. (*opts->pUsageProc)(opts, EXIT_FAILURE);
  161. leave:
  162. opts->fOptSet &= ~OPTPROC_IMMEDIATE;
  163. return res;
  164. }
  165. /**
  166. * check for preset values from a config files or envrionment variables
  167. *
  168. * @param[in,out] opts the structure with the option names to check
  169. */
  170. static tSuccess
  171. do_presets(tOptions * opts)
  172. {
  173. tOptDesc * od = NULL;
  174. if (! SUCCESSFUL(immediate_opts(opts)))
  175. return FAILURE;
  176. /*
  177. * IF this option set has a --save-opts option, then it also
  178. * has a --load-opts option. See if a command line option has disabled
  179. * option presetting.
  180. */
  181. if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT)
  182. && (opts->specOptIdx.save_opts != 0)) {
  183. od = opts->pOptDesc + opts->specOptIdx.save_opts + 1;
  184. if (DISABLED_OPT(od))
  185. return SUCCESS;
  186. }
  187. /*
  188. * Until we return from this procedure, disable non-presettable opts
  189. */
  190. opts->fOptSet |= OPTPROC_PRESETTING;
  191. /*
  192. * IF there are no config files,
  193. * THEN do any environment presets and leave.
  194. */
  195. if (opts->papzHomeList == NULL) {
  196. env_presets(opts, ENV_ALL);
  197. }
  198. else {
  199. env_presets(opts, ENV_IMM);
  200. /*
  201. * Check to see if environment variables have disabled presetting.
  202. */
  203. if ((od != NULL) && ! DISABLED_OPT(od))
  204. intern_file_load(opts);
  205. /*
  206. * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
  207. * variable options. Only the loading of .rc files.
  208. */
  209. env_presets(opts, ENV_NON_IMM);
  210. }
  211. opts->fOptSet &= ~OPTPROC_PRESETTING;
  212. return SUCCESS;
  213. }
  214. /**
  215. * AutoOpts initialization
  216. *
  217. * @param[in,out] opts the structure to initialize
  218. * @param[in] a_ct program argument count
  219. * @param[in] a_v program argument vector
  220. */
  221. LOCAL bool
  222. ao_initialize(tOptions * opts, int a_ct, char ** a_v)
  223. {
  224. if ((opts->fOptSet & OPTPROC_INITDONE) != 0)
  225. return true;
  226. opts->origArgCt = (unsigned int)a_ct;
  227. opts->origArgVect = a_v;
  228. opts->fOptSet |= OPTPROC_INITDONE;
  229. if (HAS_pzPkgDataDir(opts))
  230. program_pkgdatadir = opts->pzPkgDataDir;
  231. if (! SUCCESSFUL(do_presets(opts)))
  232. return false;
  233. /*
  234. * IF option name conversion was suppressed but it is not suppressed
  235. * for the command line, then it's time to translate option names.
  236. * Usage text will not get retranslated.
  237. */
  238. if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
  239. && (opts->pTransProc != NULL)
  240. && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG)
  241. ) {
  242. opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
  243. (*opts->pTransProc)();
  244. }
  245. if ((opts->fOptSet & OPTPROC_REORDER) != 0)
  246. optionSort(opts);
  247. opts->curOptIdx = 1;
  248. opts->pzCurOpt = NULL;
  249. return true;
  250. }
  251. /** @}
  252. *
  253. * Local Variables:
  254. * mode: C
  255. * c-file-style: "stroustrup"
  256. * indent-tabs-mode: nil
  257. * End:
  258. * end of autoopts/initialize.c */