Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / ntp / dist / sntp / libopts / restore.c
blob82f6c7a3fc9ab1371d904f9909eb273a00d1a103
1 /* $NetBSD$ */
4 /*
5 * restore.c Id: 6f5237ba2586755d8ca354f325fc00e7fa1395ec
6 * Time-stamp: "2007-07-04 11:34:40 bkorb"
8 * This module's routines will save the current option state to memory
9 * and restore it. If saved prior to the initial optionProcess call,
10 * then the initial state will be restored.
12 * This file is part of AutoOpts, a companion to AutoGen.
13 * AutoOpts is free software.
14 * AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved
16 * AutoOpts is available under any one of two licenses. The license
17 * in use must be one of these two and the choice is under the control
18 * of the user of the license.
20 * The GNU Lesser General Public License, version 3 or later
21 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
23 * The Modified Berkeley Software Distribution License
24 * See the file "COPYING.mbsd"
26 * These files have the following md5sums:
28 * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
29 * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
30 * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
34 * optionFixupSavedOpts Really, it just wipes out option state for
35 * options that are troublesome to copy. viz., stacked strings and
36 * hierarcicaly valued option args. We do duplicate string args that
37 * have been marked as allocated though.
39 static void
40 fixupSavedOptionArgs(tOptions* pOpts)
42 tOptions* p = pOpts->pSavedState;
43 tOptDesc* pOD = pOpts->pOptDesc;
44 int ct = pOpts->optCt;
47 * Make sure that allocated stuff is only referenced in the
48 * archived copy of the data.
50 for (; ct-- > 0; pOD++) {
51 switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
52 case OPARG_TYPE_STRING:
53 if (pOD->fOptState & OPTST_STACKED) {
54 tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
55 q->optCookie = NULL;
57 if (pOD->fOptState & OPTST_ALLOC_ARG) {
58 tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
59 AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg");
61 break;
63 case OPARG_TYPE_HIERARCHY:
65 tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
66 q->optCookie = NULL;
72 /*=export_func optionSaveState
74 * what: saves the option state to memory
75 * arg: tOptions*, pOpts, program options descriptor
77 * doc:
79 * This routine will allocate enough memory to save the current option
80 * processing state. If this routine has been called before, that memory
81 * will be reused. You may only save one copy of the option state. This
82 * routine may be called before optionProcess(3AO). If you do call it
83 * before the first call to optionProcess, then you may also change the
84 * contents of argc/argv after you call optionRestore(3AO)
86 * In fact, more strongly put: it is safest to only use this function
87 * before having processed any options. In particular, the saving and
88 * restoring of stacked string arguments and hierarchical values is
89 * disabled. The values are not saved.
91 * err: If it fails to allocate the memory,
92 * it will print a message to stderr and exit.
93 * Otherwise, it will always succeed.
94 =*/
95 void
96 optionSaveState(tOptions* pOpts)
98 tOptions* p = (tOptions*)pOpts->pSavedState;
100 if (p == NULL) {
101 size_t sz = sizeof( *pOpts ) + (pOpts->optCt * sizeof( tOptDesc ));
102 p = AGALOC( sz, "saved option state" );
103 if (p == NULL) {
104 tCC* pzName = pOpts->pzProgName;
105 if (pzName == NULL) {
106 pzName = pOpts->pzPROGNAME;
107 if (pzName == NULL)
108 pzName = zNil;
110 fprintf( stderr, zCantSave, pzName, sz );
111 exit( EXIT_FAILURE );
114 pOpts->pSavedState = p;
117 memcpy( p, pOpts, sizeof( *p ));
118 memcpy( p + 1, pOpts->pOptDesc, p->optCt * sizeof( tOptDesc ));
120 fixupSavedOptionArgs(pOpts);
124 /*=export_func optionRestore
126 * what: restore option state from memory copy
127 * arg: tOptions*, pOpts, program options descriptor
129 * doc: Copy back the option state from saved memory.
130 * The allocated memory is left intact, so this routine can be
131 * called repeatedly without having to call optionSaveState again.
132 * If you are restoring a state that was saved before the first call
133 * to optionProcess(3AO), then you may change the contents of the
134 * argc/argv parameters to optionProcess.
136 * err: If you have not called @code{optionSaveState} before, a diagnostic is
137 * printed to @code{stderr} and exit is called.
139 void
140 optionRestore( tOptions* pOpts )
142 tOptions* p = (tOptions*)pOpts->pSavedState;
144 if (p == NULL) {
145 tCC* pzName = pOpts->pzProgName;
146 if (pzName == NULL) {
147 pzName = pOpts->pzPROGNAME;
148 if (pzName == NULL)
149 pzName = zNil;
151 fprintf( stderr, zNoState, pzName );
152 exit( EXIT_FAILURE );
155 pOpts->pSavedState = NULL;
156 optionFree(pOpts);
158 memcpy( pOpts, p, sizeof( *p ));
159 memcpy( pOpts->pOptDesc, p+1, p->optCt * sizeof( tOptDesc ));
160 pOpts->pSavedState = p;
162 fixupSavedOptionArgs(pOpts);
165 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
167 /*=export_func optionFree
169 * what: free allocated option processing memory
170 * arg: tOptions*, pOpts, program options descriptor
172 * doc: AutoOpts sometimes allocates memory and puts pointers to it in the
173 * option state structures. This routine deallocates all such memory.
175 * err: As long as memory has not been corrupted,
176 * this routine is always successful.
178 void
179 optionFree( tOptions* pOpts )
181 free_saved_state:
183 tOptDesc* p = pOpts->pOptDesc;
184 int ct = pOpts->optCt;
185 do {
186 if (p->fOptState & OPTST_ALLOC_ARG) {
187 AGFREE(p->optArg.argString);
188 p->optArg.argString = NULL;
189 p->fOptState &= ~OPTST_ALLOC_ARG;
192 switch (OPTST_GET_ARGTYPE(p->fOptState)) {
193 case OPARG_TYPE_STRING:
194 #ifdef WITH_LIBREGEX
195 if ( (p->fOptState & OPTST_STACKED)
196 && (p->optCookie != NULL)) {
197 p->optArg.argString = ".*";
198 optionUnstackArg(pOpts, p);
200 #else
201 /* leak memory */;
202 #endif
203 break;
205 case OPARG_TYPE_HIERARCHY:
206 if (p->optCookie != NULL)
207 unloadNestedArglist(p->optCookie);
208 break;
211 p->optCookie = NULL;
212 } while (p++, --ct > 0);
214 if (pOpts->pSavedState != NULL) {
215 tOptions * p = (tOptions*)pOpts->pSavedState;
216 memcpy( pOpts, p, sizeof( *p ));
217 memcpy( pOpts->pOptDesc, p+1, p->optCt * sizeof( tOptDesc ));
218 AGFREE( pOpts->pSavedState );
219 pOpts->pSavedState = NULL;
220 goto free_saved_state;
224 * Local Variables:
225 * mode: C
226 * c-file-style: "stroustrup"
227 * indent-tabs-mode: nil
228 * End:
229 * end of autoopts/restore.c */