#include <ft2build.h>#include FT_EXCEPT_H FT_BASE_DEF( void ) ft_cleanup_stack_init( FT_CleanupStack stack, FT_Memory memory ) { stack->chunk = &stack->chunk_0; stack->top = stack->chunk->items; stack->limit = stack->top + FT_CLEANUP_CHUNK_SIZE; stack->chunk_0.link = NULL; stack->memory = memory; } FT_BASE_DEF( void ) ft_cleanup_stack_done( FT_CleanupStack stack ) { FT_Memory memory = stack->memory; FT_CleanupChunk chunk, next; for (;;) { chunk = stack->chunk; if ( chunk == &stack->chunk_0 ) break; stack->chunk = chunk->link; FT_Free( chunk, memory ); } stack->memory = NULL; } FT_BASE_DEF( void ) ft_cleanup_stack_push( FT_CleanupStack stack, FT_Pointer item, FT_CleanupFunc item_func, FT_Pointer item_data ) { FT_CleanupItem top; FT_ASSERT( stack && stack->chunk && stack->top ); FT_ASSERT( item && item_func ); top = stack->top; top->item = item; top->item_func = item_func; top->item_data = item_data; top ++; if ( top == stack->limit ) { FT_CleanupChunk chunk; chunk = FT_QAlloc( sizeof(*chunk), stack->memory ); chunk->link = stack->chunk; stack->chunk = chunk; stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; top = chunk->items; } stack->top = top; } FT_BASE_DEF( void ) ft_cleanup_stack_pop( FT_CleanupStack stack, FT_Int destroy ) { FT_CleanupItem top; FT_ASSERT( stack && stack->chunk && stack->top ); top = stack->top; if ( top == stack->chunk->items ) { FT_CleanupChunk chunk; chunk = stack->chunk; if ( chunk == &stack->chunk_0 ) { FT_ERROR(( "cleanup.pop: empty cleanup stack !!\n" )); ft_cleanup_throw( stack, FT_Err_EmptyCleanupStack ); } chunk = chunk->link; FT_QFree( stack->chunk, stack->memory ); stack->chunk = chunk; stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; top = stack->limit; } top --; if ( destroy ) top->item_func( top->item, top->item_data ); top->item = NULL; top->item_func = NULL; top->item_data = NULL; stack->top = top; } FT_BASE_DEF( FT_CleanupItem ) ft_cleanup_stack_peek( FT_CleanupStack stack ) { FT_CleanupItem top; FT_CleanupChunk chunk; FT_ASSERT( stack && stack->chunk && stack->top ); top = stack->top; chunk = stack->chunk; if ( top > chunk->items ) top--; else { chunk = chunk->link; top = NULL; if ( chunk != NULL ) top = chunk->items + FT_CLEANUP_CHUNK_SIZE - 1; } return top; } FT_BASE_DEF( void ) ft_xhandler_enter( FT_XHandler xhandler, FT_Memory memory ) { FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); xhandler->previous = stack->xhandler; xhandler->cleanup = stack->top; xhandler->error = 0; stack->xhandler = xhandler; } FT_BASE_DEF( void ) ft_xhandler_exit( FT_XHandler xhandler ) { FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); stack->xhandler = xhandler->previous; xhandler->previous = NULL; xhandler->error = error; xhandler->cleanup = NULL; } FT_BASE_DEF( void ) ft_cleanup_throw( FT_CleanupStack stack, FT_Error error ) { FT_XHandler xhandler = stack->xhandler; if ( xhandler == NULL ) { /* no exception handler was registered. this */ /* means that we have an un-handled exception */ /* the only thing we can do is _PANIC_ and */ /* halt the current program.. */ /* */ FT_ERROR(( "FREETYPE PANIC: An un-handled exception occured. Program aborted" )); ft_exit(1); } /* cleanup the stack until we reach the handler's */ /* starting stack location.. */ xhandler->error = error; longmp( xhandler->jump_buffer, 1 ); }
#include <ft2build.h>
#include FT_EXCEPT_H
FT_BASE_DEF( void )
ft_cleanup_stack_init( FT_CleanupStack stack,
FT_Memory memory )
{
stack->chunk = &stack->chunk_0;
stack->top = stack->chunk->items;
stack->limit = stack->top + FT_CLEANUP_CHUNK_SIZE;
stack->chunk_0.link = NULL;
stack->memory = memory;
}
FT_BASE_DEF( void )
ft_cleanup_stack_done( FT_CleanupStack stack )
{
FT_Memory memory = stack->memory;
FT_CleanupChunk chunk, next;
for (;;)
{
chunk = stack->chunk;
if ( chunk == &stack->chunk_0 )
break;
stack->chunk = chunk->link;
FT_Free( chunk, memory );
}
stack->memory = NULL;
}
FT_BASE_DEF( void )
ft_cleanup_stack_push( FT_CleanupStack stack,
FT_Pointer item,
FT_CleanupFunc item_func,
FT_Pointer item_data )
{
FT_CleanupItem top;
FT_ASSERT( stack && stack->chunk && stack->top );
FT_ASSERT( item && item_func );
top = stack->top;
top->item = item;
top->item_func = item_func;
top->item_data = item_data;
top ++;
if ( top == stack->limit )
{
FT_CleanupChunk chunk;
chunk = FT_QAlloc( sizeof(*chunk), stack->memory );
chunk->link = stack->chunk;
stack->chunk = chunk;
stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE;
top = chunk->items;
}
stack->top = top;
}
FT_BASE_DEF( void )
ft_cleanup_stack_pop( FT_CleanupStack stack,
FT_Int destroy )
{
FT_CleanupItem top;
FT_ASSERT( stack && stack->chunk && stack->top );
top = stack->top;
if ( top == stack->chunk->items )
{
FT_CleanupChunk chunk;
chunk = stack->chunk;
if ( chunk == &stack->chunk_0 )
{
FT_ERROR(( "cleanup.pop: empty cleanup stack !!\n" ));
ft_cleanup_throw( stack, FT_Err_EmptyCleanupStack );
}
chunk = chunk->link;
FT_QFree( stack->chunk, stack->memory );
stack->chunk = chunk;
stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE;
top = stack->limit;
}
top --;
if ( destroy )
top->item_func( top->item, top->item_data );
top->item = NULL;
top->item_func = NULL;
top->item_data = NULL;
stack->top = top;
}
FT_BASE_DEF( FT_CleanupItem )
ft_cleanup_stack_peek( FT_CleanupStack stack )
{
FT_CleanupItem top;
FT_CleanupChunk chunk;
FT_ASSERT( stack && stack->chunk && stack->top );
top = stack->top;
chunk = stack->chunk;
if ( top > chunk->items )
top--;
else
{
chunk = chunk->link;
top = NULL;
if ( chunk != NULL )
top = chunk->items + FT_CLEANUP_CHUNK_SIZE - 1;
}
return top;
}
FT_BASE_DEF( void )
ft_xhandler_enter( FT_XHandler xhandler,
FT_Memory memory )
{
FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory);
xhandler->previous = stack->xhandler;
xhandler->cleanup = stack->top;
xhandler->error = 0;
stack->xhandler = xhandler;
}
FT_BASE_DEF( void )
ft_xhandler_exit( FT_XHandler xhandler )
{
FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory);
stack->xhandler = xhandler->previous;
xhandler->previous = NULL;
xhandler->error = error;
xhandler->cleanup = NULL;
}
FT_BASE_DEF( void )
ft_cleanup_throw( FT_CleanupStack stack,
FT_Error error )
{
FT_XHandler xhandler = stack->xhandler;
if ( xhandler == NULL )
{
/* no exception handler was registered. this */
/* means that we have an un-handled exception */
/* the only thing we can do is _PANIC_ and */
/* halt the current program.. */
/* */
FT_ERROR(( "FREETYPE PANIC: An un-handled exception occured. Program aborted" ));
ft_exit(1);
}
/* cleanup the stack until we reach the handler's */
/* starting stack location.. */
xhandler->error = error;
longmp( xhandler->jump_buffer, 1 );
}