Annotation of embedaddon/ntp/sntp/libopts/stack.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /**
                      3:  * \file stack.c
                      4:  *
                      5:  *  Time-stamp:      "2010-07-17 10:42:27 bkorb"
                      6:  *
                      7:  *  This is a special option processing routine that will save the
                      8:  *  argument to an option in a FIFO queue.
                      9:  *
                     10:  *  This file is part of AutoOpts, a companion to AutoGen.
                     11:  *  AutoOpts is free software.
                     12:  *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
                     13:  *
                     14:  *  AutoOpts is available under any one of two licenses.  The license
                     15:  *  in use must be one of these two and the choice is under the control
                     16:  *  of the user of the license.
                     17:  *
                     18:  *   The GNU Lesser General Public License, version 3 or later
                     19:  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
                     20:  *
                     21:  *   The Modified Berkeley Software Distribution License
                     22:  *      See the file "COPYING.mbsd"
                     23:  *
                     24:  *  These files have the following md5sums:
                     25:  *
                     26:  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
                     27:  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
                     28:  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
                     29:  */
                     30: 
                     31: #ifdef WITH_LIBREGEX
                     32: #  include REGEX_HEADER
                     33: #endif
                     34: 
                     35: /*=export_func  optionUnstackArg
                     36:  * private:
                     37:  *
                     38:  * what:  Remove option args from a stack
                     39:  * arg:   + tOptions* + pOpts    + program options descriptor +
                     40:  * arg:   + tOptDesc* + pOptDesc + the descriptor for this arg +
                     41:  *
                     42:  * doc:
                     43:  *  Invoked for options that are equivalenced to stacked options.
                     44: =*/
                     45: void
                     46: optionUnstackArg(
                     47:     tOptions*  pOpts,
                     48:     tOptDesc*  pOptDesc )
                     49: {
                     50:     int       res;
                     51: 
                     52:     tArgList* pAL;
                     53: 
                     54:     if ((pOptDesc->fOptState & OPTST_RESET) != 0)
                     55:         return;
                     56:     pAL = (tArgList*)pOptDesc->optCookie;
                     57: 
                     58:     /*
                     59:      *  IF we don't have any stacked options,
                     60:      *  THEN indicate that we don't have any of these options
                     61:      */
                     62:     if (pAL == NULL) {
                     63:         pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
                     64:         if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0)
                     65:             pOptDesc->fOptState |= OPTST_DISABLED;
                     66:         return;
                     67:     }
                     68: 
                     69: #ifdef WITH_LIBREGEX
                     70:     {
                     71:         regex_t   re;
                     72:         int       i, ct, dIdx;
                     73: 
                     74:         if (regcomp(&re, pOptDesc->optArg.argString, REG_NOSUB) != 0)
                     75:             return;
                     76: 
                     77:         /*
                     78:          *  search the list for the entry(s) to remove.  Entries that
                     79:          *  are removed are *not* copied into the result.  The source
                     80:          *  index is incremented every time.  The destination only when
                     81:          *  we are keeping a define.
                     82:          */
                     83:         for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
                     84:             tCC*      pzSrc = pAL->apzArgs[ i ];
                     85:             char*     pzEq  = strchr(pzSrc, '=');
                     86: 
                     87:             if (pzEq != NULL)
                     88:                 *pzEq = NUL;
                     89: 
                     90:             res = regexec(&re, pzSrc, (size_t)0, NULL, 0);
                     91:             switch (res) {
                     92:             case 0:
                     93:                 /*
                     94:                  *  Remove this entry by reducing the in-use count
                     95:                  *  and *not* putting the string pointer back into
                     96:                  *  the list.
                     97:                  */
                     98:                 AGFREE(pzSrc);
                     99:                 pAL->useCt--;
                    100:                 break;
                    101: 
                    102:             default:
                    103:             case REG_NOMATCH:
                    104:                 if (pzEq != NULL)
                    105:                     *pzEq = '=';
                    106: 
                    107:                 /*
                    108:                  *  IF we have dropped an entry
                    109:                  *  THEN we have to move the current one.
                    110:                  */
                    111:                 if (dIdx != i)
                    112:                     pAL->apzArgs[ dIdx ] = pzSrc;
                    113:                 dIdx++;
                    114:             }
                    115:         }
                    116: 
                    117:         regfree(&re);
                    118:     }
                    119: #else  /* not WITH_LIBREGEX */
                    120:     {
                    121:         int i, ct, dIdx;
                    122: 
                    123:         /*
                    124:          *  search the list for the entry(s) to remove.  Entries that
                    125:          *  are removed are *not* copied into the result.  The source
                    126:          *  index is incremented every time.  The destination only when
                    127:          *  we are keeping a define.
                    128:          */
                    129:         for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
                    130:             tCC*      pzSrc = pAL->apzArgs[ i ];
                    131:             char*     pzEq  = strchr(pzSrc, '=');
                    132: 
                    133:             if (pzEq != NULL)
                    134:                 *pzEq = NUL;
                    135: 
                    136:             if (strcmp(pzSrc, pOptDesc->optArg.argString) == 0) {
                    137:                 /*
                    138:                  *  Remove this entry by reducing the in-use count
                    139:                  *  and *not* putting the string pointer back into
                    140:                  *  the list.
                    141:                  */
                    142:                 AGFREE(pzSrc);
                    143:                 pAL->useCt--;
                    144:             } else {
                    145:                 if (pzEq != NULL)
                    146:                     *pzEq = '=';
                    147: 
                    148:                 /*
                    149:                  *  IF we have dropped an entry
                    150:                  *  THEN we have to move the current one.
                    151:                  */
                    152:                 if (dIdx != i)
                    153:                     pAL->apzArgs[ dIdx ] = pzSrc;
                    154:                 dIdx++;
                    155:             }
                    156:         }
                    157:     }
                    158: #endif /* WITH_LIBREGEX */
                    159:     /*
                    160:      *  IF we have unstacked everything,
                    161:      *  THEN indicate that we don't have any of these options
                    162:      */
                    163:     if (pAL->useCt == 0) {
                    164:         pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
                    165:         if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0)
                    166:             pOptDesc->fOptState |= OPTST_DISABLED;
                    167:         AGFREE((void*)pAL);
                    168:         pOptDesc->optCookie = NULL;
                    169:     }
                    170: }
                    171: 
                    172: 
                    173: /*
                    174:  *  Put an entry into an argument list.  The first argument points to
                    175:  *  a pointer to the argument list structure.  It gets passed around
                    176:  *  as an opaque address.
                    177:  */
                    178: LOCAL void
                    179: addArgListEntry(void** ppAL, void* entry)
                    180: {
                    181:     tArgList* pAL = *(void**)ppAL;
                    182: 
                    183:     /*
                    184:      *  IF we have never allocated one of these,
                    185:      *  THEN allocate one now
                    186:      */
                    187:     if (pAL == NULL) {
                    188:         pAL = (tArgList*)AGALOC(sizeof(*pAL), "new option arg stack");
                    189:         if (pAL == NULL)
                    190:             return;
                    191:         pAL->useCt   = 0;
                    192:         pAL->allocCt = MIN_ARG_ALLOC_CT;
                    193:         *ppAL = (void*)pAL;
                    194:     }
                    195: 
                    196:     /*
                    197:      *  ELSE if we are out of room
                    198:      *  THEN make it bigger
                    199:      */
                    200:     else if (pAL->useCt >= pAL->allocCt) {
                    201:         size_t sz = sizeof(*pAL);
                    202:         pAL->allocCt += INCR_ARG_ALLOC_CT;
                    203: 
                    204:         /*
                    205:          *  The base structure contains space for MIN_ARG_ALLOC_CT
                    206:          *  pointers.  We subtract it off to find our augment size.
                    207:          */
                    208:         sz += sizeof(char*) * (pAL->allocCt - MIN_ARG_ALLOC_CT);
                    209:         pAL = (tArgList*)AGREALOC((void*)pAL, sz, "expanded opt arg stack");
                    210:         if (pAL == NULL)
                    211:             return;
                    212:         *ppAL = (void*)pAL;
                    213:     }
                    214: 
                    215:     /*
                    216:      *  Insert the new argument into the list
                    217:      */
                    218:     pAL->apzArgs[ (pAL->useCt)++ ] = entry;
                    219: }
                    220: 
                    221: 
                    222: /*=export_func  optionStackArg
                    223:  * private:
                    224:  *
                    225:  * what:  put option args on a stack
                    226:  * arg:   + tOptions* + pOpts    + program options descriptor +
                    227:  * arg:   + tOptDesc* + pOptDesc + the descriptor for this arg +
                    228:  *
                    229:  * doc:
                    230:  *  Keep an entry-ordered list of option arguments.
                    231: =*/
                    232: void
                    233: optionStackArg(
                    234:     tOptions*  pOpts,
                    235:     tOptDesc*  pOD )
                    236: {
                    237:     char * pz;
                    238: 
                    239:     if ((pOD->fOptState & OPTST_RESET) != 0) {
                    240:         tArgList* pAL = (void*)pOD->optCookie;
                    241:         int ix;
                    242:         if (pAL == NULL)
                    243:             return;
                    244: 
                    245:         ix = pAL->useCt;
                    246:         while (--ix >= 0)
                    247:             AGFREE(pAL->apzArgs[ix]);
                    248:         AGFREE(pAL);
                    249: 
                    250:     } else {
                    251:         if (pOD->optArg.argString == NULL)
                    252:             return;
                    253: 
                    254:         AGDUPSTR(pz, pOD->optArg.argString, "stack arg");
                    255:         addArgListEntry(&(pOD->optCookie), (void*)pz);
                    256:     }
                    257: }
                    258: /*
                    259:  * Local Variables:
                    260:  * mode: C
                    261:  * c-file-style: "stroustrup"
                    262:  * indent-tabs-mode: nil
                    263:  * End:
                    264:  * end of autoopts/stack.c */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>