Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / ntp / sntp / libopts / stack.c
bloba984f8f39a642c85b8f01c2f9e9d96bb2f95cc65
1 /* $NetBSD$ */
4 /*
5 * stack.c
6 * Id: stack.c,v 4.13 2007/02/04 17:44:12 bkorb Exp
7 * Time-stamp: "2007-01-13 10:43:21 bkorb"
9 * This is a special option processing routine that will save the
10 * argument to an option in a FIFO queue.
14 * Automated Options copyright 1992-2007 Bruce Korb
16 * Automated Options is free software.
17 * You may redistribute it and/or modify it under the terms of the
18 * GNU General Public License, as published by the Free Software
19 * Foundation; either version 2, or (at your option) any later version.
21 * Automated Options is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with Automated Options. See the file "COPYING". If not,
28 * write to: The Free Software Foundation, Inc.,
29 * 51 Franklin Street, Fifth Floor,
30 * Boston, MA 02110-1301, USA.
32 * As a special exception, Bruce Korb gives permission for additional
33 * uses of the text contained in his release of AutoOpts.
35 * The exception is that, if you link the AutoOpts library with other
36 * files to produce an executable, this does not by itself cause the
37 * resulting executable to be covered by the GNU General Public License.
38 * Your use of that executable is in no way restricted on account of
39 * linking the AutoOpts library code into it.
41 * This exception does not however invalidate any other reasons why
42 * the executable file might be covered by the GNU General Public License.
44 * This exception applies only to the code released by Bruce Korb under
45 * the name AutoOpts. If you copy code from other sources under the
46 * General Public License into a copy of AutoOpts, as the General Public
47 * License permits, the exception does not apply to the code that you add
48 * in this way. To avoid misleading anyone as to the status of such
49 * modified files, you must delete this exception notice from them.
51 * If you write modifications of your own for AutoOpts, it is your choice
52 * whether to permit this exception to apply to your modifications.
53 * If you do not wish that, delete this exception notice.
56 #ifdef WITH_LIBREGEX
57 # include REGEX_HEADER
58 #endif
60 /*=export_func optionUnstackArg
61 * private:
63 * what: Remove option args from a stack
64 * arg: + tOptions* + pOpts + program options descriptor +
65 * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
67 * doc:
68 * Invoked for options that are equivalenced to stacked options.
69 =*/
70 void
71 optionUnstackArg(
72 tOptions* pOpts,
73 tOptDesc* pOptDesc )
75 int res;
77 tArgList* pAL = (tArgList*)pOptDesc->optCookie;
79 * IF we don't have any stacked options,
80 * THEN indicate that we don't have any of these options
82 if (pAL == NULL) {
83 pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
84 if ( (pOptDesc->fOptState & OPTST_INITENABLED) == 0)
85 pOptDesc->fOptState |= OPTST_DISABLED;
86 return;
89 #ifdef WITH_LIBREGEX
91 regex_t re;
92 int i, ct, dIdx;
94 if (regcomp( &re, pOptDesc->optArg.argString, REG_NOSUB ) != 0)
95 return;
98 * search the list for the entry(s) to remove. Entries that
99 * are removed are *not* copied into the result. The source
100 * index is incremented every time. The destination only when
101 * we are keeping a define.
103 for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
104 tCC* pzSrc = pAL->apzArgs[ i ];
105 char* pzEq = strchr( pzSrc, '=' );
107 if (pzEq != NULL)
108 *pzEq = NUL;
110 res = regexec( &re, pzSrc, (size_t)0, NULL, 0 );
111 switch (res) {
112 case 0:
114 * Remove this entry by reducing the in-use count
115 * and *not* putting the string pointer back into
116 * the list.
118 AGFREE(pzSrc);
119 pAL->useCt--;
120 break;
122 default:
123 case REG_NOMATCH:
124 if (pzEq != NULL)
125 *pzEq = '=';
128 * IF we have dropped an entry
129 * THEN we have to move the current one.
131 if (dIdx != i)
132 pAL->apzArgs[ dIdx ] = pzSrc;
133 dIdx++;
137 regfree( &re );
139 #else /* not WITH_LIBREGEX */
141 int i, ct, dIdx;
144 * search the list for the entry(s) to remove. Entries that
145 * are removed are *not* copied into the result. The source
146 * index is incremented every time. The destination only when
147 * we are keeping a define.
149 for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
150 tCC* pzSrc = pAL->apzArgs[ i ];
151 char* pzEq = strchr( pzSrc, '=' );
153 if (pzEq != NULL)
154 *pzEq = NUL;
156 if (strcmp( pzSrc, pOptDesc->optArg.argString ) == 0) {
158 * Remove this entry by reducing the in-use count
159 * and *not* putting the string pointer back into
160 * the list.
162 AGFREE(pzSrc);
163 pAL->useCt--;
164 } else {
165 if (pzEq != NULL)
166 *pzEq = '=';
169 * IF we have dropped an entry
170 * THEN we have to move the current one.
172 if (dIdx != i)
173 pAL->apzArgs[ dIdx ] = pzSrc;
174 dIdx++;
178 #endif /* WITH_LIBREGEX */
180 * IF we have unstacked everything,
181 * THEN indicate that we don't have any of these options
183 if (pAL->useCt == 0) {
184 pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
185 if ( (pOptDesc->fOptState & OPTST_INITENABLED) == 0)
186 pOptDesc->fOptState |= OPTST_DISABLED;
187 AGFREE( (void*)pAL );
188 pOptDesc->optCookie = NULL;
194 * Put an entry into an argument list. The first argument points to
195 * a pointer to the argument list structure. It gets passed around
196 * as an opaque address.
198 LOCAL void
199 addArgListEntry( void** ppAL, void* entry )
201 tArgList* pAL = *(void**)ppAL;
204 * IF we have never allocated one of these,
205 * THEN allocate one now
207 if (pAL == NULL) {
208 pAL = (tArgList*)AGALOC( sizeof( *pAL ), "new option arg stack" );
209 if (pAL == NULL)
210 return;
211 pAL->useCt = 0;
212 pAL->allocCt = MIN_ARG_ALLOC_CT;
213 *ppAL = (void*)pAL;
217 * ELSE if we are out of room
218 * THEN make it bigger
220 else if (pAL->useCt >= pAL->allocCt) {
221 size_t sz = sizeof( *pAL );
222 pAL->allocCt += INCR_ARG_ALLOC_CT;
225 * The base structure contains space for MIN_ARG_ALLOC_CT
226 * pointers. We subtract it off to find our augment size.
228 sz += sizeof(char*) * (pAL->allocCt - MIN_ARG_ALLOC_CT);
229 pAL = (tArgList*)AGREALOC( (void*)pAL, sz, "expanded opt arg stack" );
230 if (pAL == NULL)
231 return;
232 *ppAL = (void*)pAL;
236 * Insert the new argument into the list
238 pAL->apzArgs[ (pAL->useCt)++ ] = entry;
242 /*=export_func optionStackArg
243 * private:
245 * what: put option args on a stack
246 * arg: + tOptions* + pOpts + program options descriptor +
247 * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
249 * doc:
250 * Keep an entry-ordered list of option arguments.
252 void
253 optionStackArg(
254 tOptions* pOpts,
255 tOptDesc* pOD )
257 char * pz;
259 if (pOD->optArg.argString == NULL)
260 return;
262 AGDUPSTR(pz, pOD->optArg.argString, "stack arg");
263 addArgListEntry( &(pOD->optCookie), (void*)pz );
266 * Local Variables:
267 * mode: C
268 * c-file-style: "stroustrup"
269 * indent-tabs-mode: nil
270 * End:
271 * end of autoopts/stack.c */