258 lines
4 KiB
C
258 lines
4 KiB
C
|
/*++
|
||
|
|
||
|
CLEANUP.C
|
||
|
|
||
|
CleanupOptionData code.
|
||
|
|
||
|
Created, 6/25/1997 when it was impossible to keep making myself believe
|
||
|
that I could go without allocating any memory in the option parser.
|
||
|
|
||
|
Now, if you care, you're supposed to call CleanupOptionData().
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
#include "private.h"
|
||
|
|
||
|
/* OptionDealloc:
|
||
|
|
||
|
same as free() right now. It should change if/when OptionAlloc
|
||
|
changes */
|
||
|
|
||
|
VOID
|
||
|
OptionDealloc( IN PVOID pTarget ) {
|
||
|
|
||
|
ASSERT( pTarget != NULL );
|
||
|
|
||
|
free ( pTarget );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
OptionAddToList( IN PVOID pQueue,
|
||
|
IN PVOID pItem,
|
||
|
IN DEALLOC_METHOD eDealloc) {
|
||
|
|
||
|
PSAVENODE pNode;
|
||
|
PSAVEQUEUE pList;
|
||
|
|
||
|
if ( !pQueue ) {
|
||
|
|
||
|
return TRUE; // vacuous
|
||
|
|
||
|
} else {
|
||
|
|
||
|
pList = (PSAVEQUEUE) pQueue;
|
||
|
|
||
|
}
|
||
|
|
||
|
if( OptionAlloc( NULL, &pNode, sizeof( SAVENODE ) ) ) {
|
||
|
|
||
|
pNode->DataElement = pItem;
|
||
|
pNode->DeallocMethod = eDealloc;
|
||
|
pNode->next = NULL;
|
||
|
|
||
|
if ( pList->FirstNode == NULL ) {
|
||
|
|
||
|
ASSERT( pList->LastNode == NULL );
|
||
|
|
||
|
pList->FirstNode = pNode;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
pList->LastNode->next = pNode;
|
||
|
|
||
|
}
|
||
|
|
||
|
pList->LastNode = pNode;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
OptionResizeMemory( IN PVOID pSaveQueue,
|
||
|
OUT PVOID *ppResizedMemory,
|
||
|
IN ULONG newSize ) {
|
||
|
|
||
|
ASSERT( ppResizedMemory != NULL );
|
||
|
ASSERT( newSize > 0 );
|
||
|
// ASSERT( *ppResizedMemory != NULL ); // unuseful assertion.
|
||
|
|
||
|
if ( *ppResizedMemory ) {
|
||
|
|
||
|
PSAVENODE pNode = NULL;
|
||
|
PVOID pDataElement;
|
||
|
|
||
|
pDataElement = *ppResizedMemory;
|
||
|
|
||
|
if ( pSaveQueue ) {
|
||
|
|
||
|
PSAVEQUEUE pQ;
|
||
|
pQ = (PSAVEQUEUE) pSaveQueue;
|
||
|
|
||
|
for ( pNode = pQ->FirstNode ;
|
||
|
pNode != NULL;
|
||
|
pNode = pNode->next ) {
|
||
|
|
||
|
if ( pNode->DataElement == pDataElement ) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( !pNode ) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pDataElement = realloc( pDataElement, newSize ) ;
|
||
|
|
||
|
if ( pDataElement == NULL ) {
|
||
|
|
||
|
fprintf( stderr,
|
||
|
"OptionResizeMemory failed to realloc for %d bytes.\n",
|
||
|
newSize );
|
||
|
|
||
|
// allocation failed.
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
*ppResizedMemory = pDataElement;
|
||
|
|
||
|
if ( pNode ) {
|
||
|
|
||
|
// must change this within the list as well.
|
||
|
|
||
|
pNode->DataElement = pDataElement;
|
||
|
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
/* just like realloc, if you pass NULL, we'll just malloc the data
|
||
|
anyway. This is just more convenient. */
|
||
|
|
||
|
return OptionAlloc( pSaveQueue, ppResizedMemory, newSize );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* OptionAlloc:
|
||
|
|
||
|
currently, malloc.
|
||
|
|
||
|
if you change the method of allocation, you must also change
|
||
|
OptionDealloc above */
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
OptionAlloc( IN PSAVEQUEUE pQueue,
|
||
|
OUT PVOID *pTarget,
|
||
|
IN ULONG size ) {
|
||
|
|
||
|
PVOID ret;
|
||
|
|
||
|
ASSERT( pTarget != NULL );
|
||
|
ASSERT( size > 0 );
|
||
|
|
||
|
ret = malloc( size );
|
||
|
|
||
|
if ( ret ) {
|
||
|
|
||
|
memset( ret, 0, size );
|
||
|
|
||
|
if ( OptionAddToList( pQueue, ret, DeallocWithOptionDealloc ) ) {
|
||
|
|
||
|
*pTarget = ret;
|
||
|
|
||
|
return TRUE;
|
||
|
} else {
|
||
|
|
||
|
free( ret );
|
||
|
|
||
|
// fallthrough
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*pTarget = NULL;
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
CleanupOptionDataEx( IN PVOID pVoid ) {
|
||
|
|
||
|
ULONG i;
|
||
|
PSAVEQUEUE pQueue;
|
||
|
|
||
|
ASSERT( pVoid != NULL );
|
||
|
|
||
|
pQueue = ( PSAVEQUEUE ) pVoid;
|
||
|
|
||
|
if ( pQueue->FirstNode != NULL ) {
|
||
|
|
||
|
PSAVENODE p;
|
||
|
PSAVENODE q;
|
||
|
|
||
|
ASSERT( pQueue->LastNode != NULL );
|
||
|
OPTIONS_DEBUG( "CleanupOptionDataEx: Freelist is nonempty.\n" );
|
||
|
|
||
|
for ( p = pQueue->FirstNode ;
|
||
|
p != NULL ;
|
||
|
p = q ) {
|
||
|
|
||
|
q = p->next;
|
||
|
|
||
|
switch( p->DeallocMethod ) {
|
||
|
|
||
|
case DeallocWithFree:
|
||
|
|
||
|
free( p->DataElement );
|
||
|
break;
|
||
|
|
||
|
case DeallocWithLocalFree:
|
||
|
LocalFree( p->DataElement );
|
||
|
break;
|
||
|
|
||
|
case DeallocWithOptionDealloc:
|
||
|
|
||
|
OptionDealloc( p->DataElement );
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
|
||
|
ASSERT_NOTREACHED( "unknown dealloc flag. Bleah!" );
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
OptionDealloc( p );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
} else {
|
||
|
|
||
|
OPTIONS_DEBUG( "CleanupOptionDataEx: Freelist is empty.\n" );
|
||
|
|
||
|
ASSERT( pQueue->LastNode == NULL );
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|