コード例 #1
0
/*=export_func  optionUnloadNested
 *
 * what:  Deallocate the memory for a nested value
 * arg:   + tOptionValue const * + pOptVal + the hierarchical value +
 *
 * doc:
 *  A nested value needs to be deallocated.  The pointer passed in should
 *  have been gotten from a call to @code{configFileLoad()} (See
 *  @pxref{libopts-configFileLoad}).
=*/
void
optionUnloadNested( tOptionValue const * pOV )
{
    if (pOV == NULL) return;
    if (pOV->valType != OPARG_TYPE_HIERARCHY) {
        errno = EINVAL;
        return;
    }

    unloadNestedArglist( pOV->v.nestVal );

    AGFREE(pOV);
}
コード例 #2
0
/*  unloadNestedArglist
 *
 *  Deallocate a list of option arguments.  This must have been gotten from
 *  a hierarchical option argument, not a stacked list of strings.  It is
 *  an internal call, so it is not validated.  The caller is responsible for
 *  knowing what they are doing.
 */
static void
unloadNestedArglist( tArgList* pAL )
{
    int ct = pAL->useCt;
    tCC** ppNV = pAL->apzArgs;

    while (ct-- > 0) {
        tOptionValue* pNV = (tOptionValue*)(void*)(intptr_t)*(ppNV++);
        if (pNV->valType == OPARG_TYPE_HIERARCHY)
            unloadNestedArglist( pNV->v.nestVal );
        AGFREE( pNV );
    }

    AGFREE( pAL );
}
コード例 #3
0
/*=export_func optionFree
 *
 * what:  free allocated option processing memory
 * arg:   tOptions*, pOpts, program options descriptor
 *
 * doc:   AutoOpts sometimes allocates memory and puts pointers to it in the
 *        option state structures.  This routine deallocates all such memory.
 *
 * err:   As long as memory has not been corrupted,
 *        this routine is always successful.
=*/
void
optionFree( tOptions* pOpts )
{
 free_saved_state:
    {
        tOptDesc* p = pOpts->pOptDesc;
        int ct = pOpts->optCt;
        do  {
            if (p->fOptState & OPTST_ALLOC_ARG) {
                AGFREE(p->optArg.argString);
                p->optArg.argString = NULL;
                p->fOptState &= ~OPTST_ALLOC_ARG;
            }

            switch (OPTST_GET_ARGTYPE(p->fOptState)) {
            case OPARG_TYPE_STRING:
#ifdef WITH_LIBREGEX
                if (  (p->fOptState & OPTST_STACKED)
                   && (p->optCookie != NULL)) {
                    p->optArg.argString = ".*";
                    optionUnstackArg(pOpts, p);
                }
#else
                /* leak memory */;
#endif
                break;

            case OPARG_TYPE_HIERARCHY:
                if (p->optCookie != NULL)
                    unloadNestedArglist(p->optCookie);
                break;
            }

            p->optCookie = NULL;
        } while (p++, --ct > 0);
    }
    if (pOpts->pSavedState != NULL) {
        tOptions * p = (tOptions*)pOpts->pSavedState;
        memcpy( pOpts, p, sizeof( *p ));
        memcpy( pOpts->pOptDesc, p+1, p->optCt * sizeof( tOptDesc ));
        AGFREE( pOpts->pSavedState );
        pOpts->pSavedState = NULL;
        goto free_saved_state;
    }
}