Annotation of embedaddon/ntp/sntp/libopts/restore.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * \file restore.c
4: *
5: * Time-stamp: "2010-08-22 11:04:00 bkorb"
6: *
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.
10: *
11: * This file is part of AutoOpts, a companion to AutoGen.
12: * AutoOpts is free software.
13: * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
14: *
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.
18: *
19: * The GNU Lesser General Public License, version 3 or later
20: * See the files "COPYING.lgplv3" and "COPYING.gplv3"
21: *
22: * The Modified Berkeley Software Distribution License
23: * See the file "COPYING.mbsd"
24: *
25: * These files have the following md5sums:
26: *
27: * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
28: * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
29: * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
30: */
31:
32: /*
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.
37: */
38: static void
39: fixupSavedOptionArgs(tOptions* pOpts)
40: {
41: tOptions* p = pOpts->pSavedState;
42: tOptDesc* pOD = pOpts->pOptDesc;
43: int ct = pOpts->optCt;
44:
45: /*
46: * Make sure that allocated stuff is only referenced in the
47: * archived copy of the data.
48: */
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);
54: q->optCookie = NULL;
55: }
56: if (pOD->fOptState & OPTST_ALLOC_ARG) {
57: tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
58: AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg");
59: }
60: break;
61:
62: case OPARG_TYPE_HIERARCHY:
63: {
64: tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
65: q->optCookie = NULL;
66: }
67: }
68: }
69: }
70:
71: /*=export_func optionSaveState
72: *
73: * what: saves the option state to memory
74: * arg: tOptions*, pOpts, program options descriptor
75: *
76: * doc:
77: *
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)
84: *
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.
89: *
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.
93: =*/
94: void
95: optionSaveState(tOptions* pOpts)
96: {
97: tOptions* p = (tOptions*)pOpts->pSavedState;
98:
99: if (p == NULL) {
100: size_t sz = sizeof(*pOpts) + (pOpts->optCt * sizeof(tOptDesc));
101: p = AGALOC(sz, "saved option state");
102: if (p == NULL) {
103: tCC* pzName = pOpts->pzProgName;
104: if (pzName == NULL) {
105: pzName = pOpts->pzPROGNAME;
106: if (pzName == NULL)
107: pzName = zNil;
108: }
109: fprintf(stderr, zCantSave, pzName, sz);
110: exit(EXIT_FAILURE);
111: }
112:
113: pOpts->pSavedState = p;
114: }
115:
116: memcpy(p, pOpts, sizeof(*p));
117: memcpy(p + 1, pOpts->pOptDesc, p->optCt * sizeof(tOptDesc));
118:
119: fixupSavedOptionArgs(pOpts);
120: }
121:
122:
123: /*=export_func optionRestore
124: *
125: * what: restore option state from memory copy
126: * arg: tOptions*, pOpts, program options descriptor
127: *
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.
134: *
135: * err: If you have not called @code{optionSaveState} before, a diagnostic is
136: * printed to @code{stderr} and exit is called.
137: =*/
138: void
139: optionRestore(tOptions* pOpts)
140: {
141: tOptions* p = (tOptions*)pOpts->pSavedState;
142:
143: if (p == NULL) {
144: tCC* pzName = pOpts->pzProgName;
145: if (pzName == NULL) {
146: pzName = pOpts->pzPROGNAME;
147: if (pzName == NULL)
148: pzName = zNil;
149: }
150: fprintf(stderr, zNoState, pzName);
151: exit(EXIT_FAILURE);
152: }
153:
154: pOpts->pSavedState = NULL;
155: optionFree(pOpts);
156:
157: memcpy(pOpts, p, sizeof(*p));
158: memcpy(pOpts->pOptDesc, p+1, p->optCt * sizeof(tOptDesc));
159: pOpts->pSavedState = p;
160:
161: fixupSavedOptionArgs(pOpts);
162: }
163:
164: /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
165:
166: /*=export_func optionFree
167: *
168: * what: free allocated option processing memory
169: * arg: tOptions*, pOpts, program options descriptor
170: *
171: * doc: AutoOpts sometimes allocates memory and puts pointers to it in the
172: * option state structures. This routine deallocates all such memory.
173: *
174: * err: As long as memory has not been corrupted,
175: * this routine is always successful.
176: =*/
177: void
178: optionFree(tOptions* pOpts)
179: {
180: free_saved_state:
181: {
182: tOptDesc* p = pOpts->pOptDesc;
183: int ct = pOpts->optCt;
184: do {
185: if (p->fOptState & OPTST_ALLOC_ARG) {
186: AGFREE(p->optArg.argString);
187: p->optArg.argString = NULL;
188: p->fOptState &= ~OPTST_ALLOC_ARG;
189: }
190:
191: switch (OPTST_GET_ARGTYPE(p->fOptState)) {
192: case OPARG_TYPE_STRING:
193: #ifdef WITH_LIBREGEX
194: if ( (p->fOptState & OPTST_STACKED)
195: && (p->optCookie != NULL)) {
196: p->optArg.argString = ".*";
197: optionUnstackArg(pOpts, p);
198: }
199: #else
200: /* leak memory */;
201: #endif
202: break;
203:
204: case OPARG_TYPE_HIERARCHY:
205: if (p->optCookie != NULL)
206: unload_arg_list(p->optCookie);
207: break;
208: }
209:
210: p->optCookie = NULL;
211: } while (p++, --ct > 0);
212: }
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;
220: }
221: }
222: /*
223: * Local Variables:
224: * mode: C
225: * c-file-style: "stroustrup"
226: * indent-tabs-mode: nil
227: * End:
228: * end of autoopts/restore.c */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>