/*=export_func optionRestore * * what: restore option state from memory copy * arg: tOptions*, pOpts, program options descriptor * * doc: Copy back the option state from saved memory. * The allocated memory is left intact, so this routine can be * called repeatedly without having to call optionSaveState again. * If you are restoring a state that was saved before the first call * to optionProcess(3AO), then you may change the contents of the * argc/argv parameters to optionProcess. * * err: If you have not called @code{optionSaveState} before, a diagnostic is * printed to @code{stderr} and exit is called. =*/ void optionRestore(tOptions* pOpts) { tOptions* p = (tOptions*)pOpts->pSavedState; if (p == NULL) { char const * pzName = pOpts->pzProgName; if (pzName == NULL) { pzName = pOpts->pzPROGNAME; if (pzName == NULL) pzName = zNil; } fprintf(stderr, zNoState, pzName); option_exits(EXIT_FAILURE); } pOpts->pSavedState = NULL; optionFree(pOpts); memcpy(pOpts, p, sizeof(*p)); memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); pOpts->pSavedState = p; fixupSavedOptionArgs(pOpts); }
/*=export_func optionSaveState * * what: saves the option state to memory * arg: tOptions*, pOpts, program options descriptor * * doc: * * This routine will allocate enough memory to save the current option * processing state. If this routine has been called before, that memory * will be reused. You may only save one copy of the option state. This * routine may be called before optionProcess(3AO). If you do call it * before the first call to optionProcess, then you may also change the * contents of argc/argv after you call optionRestore(3AO) * * In fact, more strongly put: it is safest to only use this function * before having processed any options. In particular, the saving and * restoring of stacked string arguments and hierarchical values is * disabled. The values are not saved. * * err: If it fails to allocate the memory, * it will print a message to stderr and exit. * Otherwise, it will always succeed. =*/ void optionSaveState(tOptions* pOpts) { tOptions* p = (tOptions*)pOpts->pSavedState; if (p == NULL) { size_t sz = sizeof( *pOpts ) + (pOpts->optCt * sizeof( tOptDesc )); p = AGALOC( sz, "saved option state" ); if (p == NULL) { tCC* pzName = pOpts->pzProgName; if (pzName == NULL) { pzName = pOpts->pzPROGNAME; if (pzName == NULL) pzName = zNil; } fprintf( stderr, zCantSave, pzName, sz ); exit( EXIT_FAILURE ); } pOpts->pSavedState = p; } memcpy( p, pOpts, sizeof( *p )); memcpy( p + 1, pOpts->pOptDesc, p->optCt * sizeof( tOptDesc )); fixupSavedOptionArgs(pOpts); }
/*=export_func optionSaveState * * what: saves the option state to memory * arg: tOptions*, pOpts, program options descriptor * * doc: * * This routine will allocate enough memory to save the current option * processing state. If this routine has been called before, that memory * will be reused. You may only save one copy of the option state. This * routine may be called before optionProcess(3AO). If you do call it * before the first call to optionProcess, then you may also change the * contents of argc/argv after you call optionRestore(3AO) * * In fact, more strongly put: it is safest to only use this function * before having processed any options. In particular, the saving and * restoring of stacked string arguments and hierarchical values is * disabled. The values are not saved. * * err: If it fails to allocate the memory, * it will print a message to stderr and exit. * Otherwise, it will always succeed. =*/ void optionSaveState(tOptions * pOpts) { tOptions * p = (tOptions*)pOpts->pSavedState; if (p == NULL) { size_t sz = sizeof(*pOpts) + ((size_t)pOpts->optCt * sizeof(tOptDesc)); p = AGALOC(sz, "saved option state"); pOpts->pSavedState = p; } memcpy(p, pOpts, sizeof(*p)); memcpy(p + 1, pOpts->pOptDesc, (size_t)p->optCt * sizeof(tOptDesc)); fixupSavedOptionArgs(pOpts); }