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>