5 * Time-stamp: "2010-08-22 11:04:00 bkorb"
7 * This module's routines will save the current option state to memory
8 * and restore it. If saved prior to the initial optionProcess call,
9 * then the initial state will be restored.
11 * This file is part of AutoOpts, a companion to AutoGen.
12 * AutoOpts is free software.
13 * AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
15 * AutoOpts is available under any one of two licenses. The license
16 * in use must be one of these two and the choice is under the control
17 * of the user of the license.
19 * The GNU Lesser General Public License, version 3 or later
20 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
22 * The Modified Berkeley Software Distribution License
23 * See the file "COPYING.mbsd"
25 * These files have the following md5sums:
27 * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
28 * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
29 * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
33 * optionFixupSavedOpts Really, it just wipes out option state for
34 * options that are troublesome to copy. viz., stacked strings and
35 * hierarcicaly valued option args. We do duplicate string args that
36 * have been marked as allocated though.
39 fixupSavedOptionArgs(tOptions
* pOpts
)
41 tOptions
* p
= pOpts
->pSavedState
;
42 tOptDesc
* pOD
= pOpts
->pOptDesc
;
43 int ct
= pOpts
->optCt
;
46 * Make sure that allocated stuff is only referenced in the
47 * archived copy of the data.
49 for (; ct
-- > 0; pOD
++) {
50 switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
51 case OPARG_TYPE_STRING
:
52 if (pOD
->fOptState
& OPTST_STACKED
) {
53 tOptDesc
* q
= p
->pOptDesc
+ (pOD
- pOpts
->pOptDesc
);
56 if (pOD
->fOptState
& OPTST_ALLOC_ARG
) {
57 tOptDesc
* q
= p
->pOptDesc
+ (pOD
- pOpts
->pOptDesc
);
58 AGDUPSTR(q
->optArg
.argString
, pOD
->optArg
.argString
, "arg");
62 case OPARG_TYPE_HIERARCHY
:
64 tOptDesc
* q
= p
->pOptDesc
+ (pOD
- pOpts
->pOptDesc
);
71 /*=export_func optionSaveState
73 * what: saves the option state to memory
74 * arg: tOptions*, pOpts, program options descriptor
78 * This routine will allocate enough memory to save the current option
79 * processing state. If this routine has been called before, that memory
80 * will be reused. You may only save one copy of the option state. This
81 * routine may be called before optionProcess(3AO). If you do call it
82 * before the first call to optionProcess, then you may also change the
83 * contents of argc/argv after you call optionRestore(3AO)
85 * In fact, more strongly put: it is safest to only use this function
86 * before having processed any options. In particular, the saving and
87 * restoring of stacked string arguments and hierarchical values is
88 * disabled. The values are not saved.
90 * err: If it fails to allocate the memory,
91 * it will print a message to stderr and exit.
92 * Otherwise, it will always succeed.
95 optionSaveState(tOptions
* pOpts
)
97 tOptions
* p
= (tOptions
*)pOpts
->pSavedState
;
100 size_t sz
= sizeof(*pOpts
) + (pOpts
->optCt
* sizeof(tOptDesc
));
101 p
= AGALOC(sz
, "saved option state");
103 tCC
* pzName
= pOpts
->pzProgName
;
104 if (pzName
== NULL
) {
105 pzName
= pOpts
->pzPROGNAME
;
109 fprintf(stderr
, zCantSave
, pzName
, sz
);
113 pOpts
->pSavedState
= p
;
116 memcpy(p
, pOpts
, sizeof(*p
));
117 memcpy(p
+ 1, pOpts
->pOptDesc
, p
->optCt
* sizeof(tOptDesc
));
119 fixupSavedOptionArgs(pOpts
);
123 /*=export_func optionRestore
125 * what: restore option state from memory copy
126 * arg: tOptions*, pOpts, program options descriptor
128 * doc: Copy back the option state from saved memory.
129 * The allocated memory is left intact, so this routine can be
130 * called repeatedly without having to call optionSaveState again.
131 * If you are restoring a state that was saved before the first call
132 * to optionProcess(3AO), then you may change the contents of the
133 * argc/argv parameters to optionProcess.
135 * err: If you have not called @code{optionSaveState} before, a diagnostic is
136 * printed to @code{stderr} and exit is called.
139 optionRestore(tOptions
* pOpts
)
141 tOptions
* p
= (tOptions
*)pOpts
->pSavedState
;
144 tCC
* pzName
= pOpts
->pzProgName
;
145 if (pzName
== NULL
) {
146 pzName
= pOpts
->pzPROGNAME
;
150 fprintf(stderr
, zNoState
, pzName
);
154 pOpts
->pSavedState
= NULL
;
157 memcpy(pOpts
, p
, sizeof(*p
));
158 memcpy(pOpts
->pOptDesc
, p
+1, p
->optCt
* sizeof(tOptDesc
));
159 pOpts
->pSavedState
= p
;
161 fixupSavedOptionArgs(pOpts
);
164 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
166 /*=export_func optionFree
168 * what: free allocated option processing memory
169 * arg: tOptions*, pOpts, program options descriptor
171 * doc: AutoOpts sometimes allocates memory and puts pointers to it in the
172 * option state structures. This routine deallocates all such memory.
174 * err: As long as memory has not been corrupted,
175 * this routine is always successful.
178 optionFree(tOptions
* pOpts
)
182 tOptDesc
* p
= pOpts
->pOptDesc
;
183 int ct
= pOpts
->optCt
;
185 if (p
->fOptState
& OPTST_ALLOC_ARG
) {
186 AGFREE(p
->optArg
.argString
);
187 p
->optArg
.argString
= NULL
;
188 p
->fOptState
&= ~OPTST_ALLOC_ARG
;
191 switch (OPTST_GET_ARGTYPE(p
->fOptState
)) {
192 case OPARG_TYPE_STRING
:
194 if ( (p
->fOptState
& OPTST_STACKED
)
195 && (p
->optCookie
!= NULL
)) {
196 p
->optArg
.argString
= ".*";
197 optionUnstackArg(pOpts
, p
);
204 case OPARG_TYPE_HIERARCHY
:
205 if (p
->optCookie
!= NULL
)
206 unload_arg_list(p
->optCookie
);
211 } while (p
++, --ct
> 0);
213 if (pOpts
->pSavedState
!= NULL
) {
214 tOptions
* p
= (tOptions
*)pOpts
->pSavedState
;
215 memcpy(pOpts
, p
, sizeof(*p
));
216 memcpy(pOpts
->pOptDesc
, p
+1, p
->optCt
* sizeof(tOptDesc
));
217 AGFREE(pOpts
->pSavedState
);
218 pOpts
->pSavedState
= NULL
;
219 goto free_saved_state
;
225 * c-file-style: "stroustrup"
226 * indent-tabs-mode: nil
228 * end of autoopts/restore.c */