File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / sntp / libopts / stack.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 7 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>