5 * This module's routines will save the current option state to memory
6 * and restore it. If saved prior to the initial optionProcess call,
7 * then the initial state will be restored.
13 * This file is part of AutoOpts, a companion to AutoGen.
14 * AutoOpts is free software.
15 * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
17 * AutoOpts is available under any one of two licenses. The license
18 * in use must be one of these two and the choice is under the control
19 * of the user of the license.
21 * The GNU Lesser General Public License, version 3 or later
22 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
24 * The Modified Berkeley Software Distribution License
25 * See the file "COPYING.mbsd"
27 * These files have the following sha256 sums:
29 * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
30 * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
31 * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
35 * optionFixupSavedOpts Really, it just wipes out option state for
36 * options that are troublesome to copy. viz., stacked strings and
37 * hierarcicaly valued option args. We do duplicate string args that
38 * have been marked as allocated though.
41 fixupSavedOptionArgs(tOptions * pOpts)
43 tOptions * p = pOpts->pSavedState;
44 tOptDesc * pOD = pOpts->pOptDesc;
45 int ct = pOpts->optCt;
48 * Make sure that allocated stuff is only referenced in the
49 * archived copy of the data.
51 for (; ct-- > 0; pOD++) {
52 switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
53 case OPARG_TYPE_STRING:
54 if (pOD->fOptState & OPTST_STACKED) {
55 tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc);
58 if (pOD->fOptState & OPTST_ALLOC_ARG) {
59 tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc);
60 AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg");
64 case OPARG_TYPE_HIERARCHY:
66 tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc);
73 /*=export_func optionSaveState
75 * what: saves the option state to memory
76 * arg: tOptions *, pOpts, program options descriptor
80 * This routine will allocate enough memory to save the current option
81 * processing state. If this routine has been called before, that memory
82 * will be reused. You may only save one copy of the option state. This
83 * routine may be called before optionProcess(3AO). If you do call it
84 * before the first call to optionProcess, then you may also change the
85 * contents of argc/argv after you call optionRestore(3AO)
87 * In fact, more strongly put: it is safest to only use this function
88 * before having processed any options. In particular, the saving and
89 * restoring of stacked string arguments and hierarchical values is
90 * disabled. The values are not saved.
92 * err: If it fails to allocate the memory,
93 * it will print a message to stderr and exit.
94 * Otherwise, it will always succeed.
97 optionSaveState(tOptions * pOpts)
99 tOptions * p = (tOptions *)pOpts->pSavedState;
102 size_t sz = sizeof(*pOpts)
103 + ((size_t)pOpts->optCt * sizeof(tOptDesc));
104 p = AGALOC(sz, "saved option state");
106 pOpts->pSavedState = p;
109 memcpy(p, pOpts, sizeof(*p));
110 memcpy(p + 1, pOpts->pOptDesc, (size_t)p->optCt * sizeof(tOptDesc));
112 fixupSavedOptionArgs(pOpts);
116 /*=export_func optionRestore
118 * what: restore option state from memory copy
119 * arg: tOptions *, pOpts, program options descriptor
121 * doc: Copy back the option state from saved memory.
122 * The allocated memory is left intact, so this routine can be
123 * called repeatedly without having to call optionSaveState again.
124 * If you are restoring a state that was saved before the first call
125 * to optionProcess(3AO), then you may change the contents of the
126 * argc/argv parameters to optionProcess.
128 * err: If you have not called @code{optionSaveState} before, a diagnostic is
129 * printed to @code{stderr} and exit is called.
132 optionRestore(tOptions * pOpts)
134 tOptions * p = (tOptions *)pOpts->pSavedState;
137 char const * pzName = pOpts->pzProgName;
138 if (pzName == NULL) {
139 pzName = pOpts->pzPROGNAME;
143 fprintf(stderr, zNoState, pzName);
144 option_exits(EXIT_FAILURE);
147 pOpts->pSavedState = NULL;
150 memcpy(pOpts, p, sizeof(*p));
151 memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc));
152 pOpts->pSavedState = p;
154 fixupSavedOptionArgs(pOpts);
157 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
159 /*=export_func optionFree
161 * what: free allocated option processing memory
162 * arg: tOptions *, pOpts, program options descriptor
164 * doc: AutoOpts sometimes allocates memory and puts pointers to it in the
165 * option state structures. This routine deallocates all such memory.
167 * err: As long as memory has not been corrupted,
168 * this routine is always successful.
171 optionFree(tOptions * pOpts)
175 tOptDesc * p = pOpts->pOptDesc;
176 int ct = pOpts->optCt;
178 if (p->fOptState & OPTST_ALLOC_ARG) {
179 AGFREE(p->optArg.argString);
180 p->optArg.argString = NULL;
181 p->fOptState &= ~OPTST_ALLOC_ARG;
184 switch (OPTST_GET_ARGTYPE(p->fOptState)) {
185 case OPARG_TYPE_STRING:
187 if ( (p->fOptState & OPTST_STACKED)
188 && (p->optCookie != NULL)) {
189 p->optArg.argString = ".*";
190 optionUnstackArg(pOpts, p);
197 case OPARG_TYPE_HIERARCHY:
198 if (p->optCookie != NULL)
199 unload_arg_list(p->optCookie);
204 } while (p++, --ct > 0);
206 if (pOpts->pSavedState != NULL) {
207 tOptions * p = (tOptions *)pOpts->pSavedState;
208 memcpy(pOpts, p, sizeof(*p));
209 memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc));
210 AGFREE(pOpts->pSavedState);
211 pOpts->pSavedState = NULL;
212 goto free_saved_state;
220 * c-file-style: "stroustrup"
221 * indent-tabs-mode: nil
223 * end of autoopts/restore.c */