Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / sntp / libopts / stack.c
blob79d75f680d199ec6464bfb65d6c8dc09f8c9ea74
1 /* $NetBSD$ */
4 /*
5 * stack.c
6 * Id: 9d4a7c1c6ae364a6134dc5ff01f58f08b52f1a16
7 * Time-stamp: "2008-07-30 16:56:32 bkorb"
9 * This is a special option processing routine that will save the
10 * argument to an option in a FIFO queue.
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
33 #ifdef WITH_LIBREGEX
34 # include REGEX_HEADER
35 #endif
37 /*=export_func optionUnstackArg
38 * private:
40 * what: Remove option args from a stack
41 * arg: + tOptions* + pOpts + program options descriptor +
42 * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
44 * doc:
45 * Invoked for options that are equivalenced to stacked options.
46 =*/
47 void
48 optionUnstackArg(
49 tOptions* pOpts,
50 tOptDesc* pOptDesc )
52 int res;
54 tArgList* pAL;
56 if ((pOptDesc->fOptState & OPTST_RESET) != 0)
57 return;
58 pAL = (tArgList*)pOptDesc->optCookie;
61 * IF we don't have any stacked options,
62 * THEN indicate that we don't have any of these options
64 if (pAL == NULL) {
65 pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
66 if ( (pOptDesc->fOptState & OPTST_INITENABLED) == 0)
67 pOptDesc->fOptState |= OPTST_DISABLED;
68 return;
71 #ifdef WITH_LIBREGEX
73 regex_t re;
74 int i, ct, dIdx;
76 if (regcomp( &re, pOptDesc->optArg.argString, REG_NOSUB ) != 0)
77 return;
80 * search the list for the entry(s) to remove. Entries that
81 * are removed are *not* copied into the result. The source
82 * index is incremented every time. The destination only when
83 * we are keeping a define.
85 for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
86 tCC* pzSrc = pAL->apzArgs[ i ];
87 char* pzEq = strchr( pzSrc, '=' );
89 if (pzEq != NULL)
90 *pzEq = NUL;
92 res = regexec( &re, pzSrc, (size_t)0, NULL, 0 );
93 switch (res) {
94 case 0:
96 * Remove this entry by reducing the in-use count
97 * and *not* putting the string pointer back into
98 * the list.
100 AGFREE(pzSrc);
101 pAL->useCt--;
102 break;
104 default:
105 case REG_NOMATCH:
106 if (pzEq != NULL)
107 *pzEq = '=';
110 * IF we have dropped an entry
111 * THEN we have to move the current one.
113 if (dIdx != i)
114 pAL->apzArgs[ dIdx ] = pzSrc;
115 dIdx++;
119 regfree( &re );
121 #else /* not WITH_LIBREGEX */
123 int i, ct, dIdx;
126 * search the list for the entry(s) to remove. Entries that
127 * are removed are *not* copied into the result. The source
128 * index is incremented every time. The destination only when
129 * we are keeping a define.
131 for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
132 tCC* pzSrc = pAL->apzArgs[ i ];
133 char* pzEq = strchr( pzSrc, '=' );
135 if (pzEq != NULL)
136 *pzEq = NUL;
138 if (strcmp( pzSrc, pOptDesc->optArg.argString ) == 0) {
140 * Remove this entry by reducing the in-use count
141 * and *not* putting the string pointer back into
142 * the list.
144 AGFREE(pzSrc);
145 pAL->useCt--;
146 } else {
147 if (pzEq != NULL)
148 *pzEq = '=';
151 * IF we have dropped an entry
152 * THEN we have to move the current one.
154 if (dIdx != i)
155 pAL->apzArgs[ dIdx ] = pzSrc;
156 dIdx++;
160 #endif /* WITH_LIBREGEX */
162 * IF we have unstacked everything,
163 * THEN indicate that we don't have any of these options
165 if (pAL->useCt == 0) {
166 pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
167 if ( (pOptDesc->fOptState & OPTST_INITENABLED) == 0)
168 pOptDesc->fOptState |= OPTST_DISABLED;
169 AGFREE( (void*)pAL );
170 pOptDesc->optCookie = NULL;
176 * Put an entry into an argument list. The first argument points to
177 * a pointer to the argument list structure. It gets passed around
178 * as an opaque address.
180 LOCAL void
181 addArgListEntry( void** ppAL, void* entry )
183 tArgList* pAL = *(void**)ppAL;
186 * IF we have never allocated one of these,
187 * THEN allocate one now
189 if (pAL == NULL) {
190 pAL = (tArgList*)AGALOC( sizeof( *pAL ), "new option arg stack" );
191 if (pAL == NULL)
192 return;
193 pAL->useCt = 0;
194 pAL->allocCt = MIN_ARG_ALLOC_CT;
195 *ppAL = (void*)pAL;
199 * ELSE if we are out of room
200 * THEN make it bigger
202 else if (pAL->useCt >= pAL->allocCt) {
203 size_t sz = sizeof( *pAL );
204 pAL->allocCt += INCR_ARG_ALLOC_CT;
207 * The base structure contains space for MIN_ARG_ALLOC_CT
208 * pointers. We subtract it off to find our augment size.
210 sz += sizeof(char*) * (pAL->allocCt - MIN_ARG_ALLOC_CT);
211 pAL = (tArgList*)AGREALOC( (void*)pAL, sz, "expanded opt arg stack" );
212 if (pAL == NULL)
213 return;
214 *ppAL = (void*)pAL;
218 * Insert the new argument into the list
220 pAL->apzArgs[ (pAL->useCt)++ ] = entry;
224 /*=export_func optionStackArg
225 * private:
227 * what: put option args on a stack
228 * arg: + tOptions* + pOpts + program options descriptor +
229 * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
231 * doc:
232 * Keep an entry-ordered list of option arguments.
234 void
235 optionStackArg(
236 tOptions* pOpts,
237 tOptDesc* pOD )
239 char * pz;
241 if ((pOD->fOptState & OPTST_RESET) != 0) {
242 tArgList* pAL = (void*)pOD->optCookie;
243 int ix;
244 if (pAL == NULL)
245 return;
247 ix = pAL->useCt;
248 while (--ix >= 0)
249 AGFREE(pAL->apzArgs[ix]);
250 AGFREE(pAL);
252 } else {
253 if (pOD->optArg.argString == NULL)
254 return;
256 AGDUPSTR(pz, pOD->optArg.argString, "stack arg");
257 addArgListEntry( &(pOD->optCookie), (void*)pz );
261 * Local Variables:
262 * mode: C
263 * c-file-style: "stroustrup"
264 * indent-tabs-mode: nil
265 * End:
266 * end of autoopts/stack.c */