1*37da2899SCharles.Forsyth #include <ft2build.h> 2*37da2899SCharles.Forsyth #include FT_EXCEPT_H 3*37da2899SCharles.Forsyth 4*37da2899SCharles.Forsyth 5*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_cleanup_stack_init(FT_CleanupStack stack,FT_Memory memory)6*37da2899SCharles.Forsyth ft_cleanup_stack_init( FT_CleanupStack stack, 7*37da2899SCharles.Forsyth FT_Memory memory ) 8*37da2899SCharles.Forsyth { 9*37da2899SCharles.Forsyth stack->chunk = &stack->chunk_0; 10*37da2899SCharles.Forsyth stack->top = stack->chunk->items; 11*37da2899SCharles.Forsyth stack->limit = stack->top + FT_CLEANUP_CHUNK_SIZE; 12*37da2899SCharles.Forsyth stack->chunk_0.link = NULL; 13*37da2899SCharles.Forsyth 14*37da2899SCharles.Forsyth stack->memory = memory; 15*37da2899SCharles.Forsyth } 16*37da2899SCharles.Forsyth 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_cleanup_stack_done(FT_CleanupStack stack)20*37da2899SCharles.Forsyth ft_cleanup_stack_done( FT_CleanupStack stack ) 21*37da2899SCharles.Forsyth { 22*37da2899SCharles.Forsyth FT_Memory memory = stack->memory; 23*37da2899SCharles.Forsyth FT_CleanupChunk chunk, next; 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth for (;;) 26*37da2899SCharles.Forsyth { 27*37da2899SCharles.Forsyth chunk = stack->chunk; 28*37da2899SCharles.Forsyth if ( chunk == &stack->chunk_0 ) 29*37da2899SCharles.Forsyth break; 30*37da2899SCharles.Forsyth 31*37da2899SCharles.Forsyth stack->chunk = chunk->link; 32*37da2899SCharles.Forsyth 33*37da2899SCharles.Forsyth FT_Free( chunk, memory ); 34*37da2899SCharles.Forsyth } 35*37da2899SCharles.Forsyth 36*37da2899SCharles.Forsyth stack->memory = NULL; 37*37da2899SCharles.Forsyth } 38*37da2899SCharles.Forsyth 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_cleanup_stack_push(FT_CleanupStack stack,FT_Pointer item,FT_CleanupFunc item_func,FT_Pointer item_data)42*37da2899SCharles.Forsyth ft_cleanup_stack_push( FT_CleanupStack stack, 43*37da2899SCharles.Forsyth FT_Pointer item, 44*37da2899SCharles.Forsyth FT_CleanupFunc item_func, 45*37da2899SCharles.Forsyth FT_Pointer item_data ) 46*37da2899SCharles.Forsyth { 47*37da2899SCharles.Forsyth FT_CleanupItem top; 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth 50*37da2899SCharles.Forsyth FT_ASSERT( stack && stack->chunk && stack->top ); 51*37da2899SCharles.Forsyth FT_ASSERT( item && item_func ); 52*37da2899SCharles.Forsyth 53*37da2899SCharles.Forsyth top = stack->top; 54*37da2899SCharles.Forsyth 55*37da2899SCharles.Forsyth top->item = item; 56*37da2899SCharles.Forsyth top->item_func = item_func; 57*37da2899SCharles.Forsyth top->item_data = item_data; 58*37da2899SCharles.Forsyth 59*37da2899SCharles.Forsyth top ++; 60*37da2899SCharles.Forsyth 61*37da2899SCharles.Forsyth if ( top == stack->limit ) 62*37da2899SCharles.Forsyth { 63*37da2899SCharles.Forsyth FT_CleanupChunk chunk; 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth chunk = FT_QAlloc( sizeof(*chunk), stack->memory ); 66*37da2899SCharles.Forsyth 67*37da2899SCharles.Forsyth chunk->link = stack->chunk; 68*37da2899SCharles.Forsyth stack->chunk = chunk; 69*37da2899SCharles.Forsyth stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; 70*37da2899SCharles.Forsyth top = chunk->items; 71*37da2899SCharles.Forsyth } 72*37da2899SCharles.Forsyth 73*37da2899SCharles.Forsyth stack->top = top; 74*37da2899SCharles.Forsyth } 75*37da2899SCharles.Forsyth 76*37da2899SCharles.Forsyth 77*37da2899SCharles.Forsyth 78*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_cleanup_stack_pop(FT_CleanupStack stack,FT_Int destroy)79*37da2899SCharles.Forsyth ft_cleanup_stack_pop( FT_CleanupStack stack, 80*37da2899SCharles.Forsyth FT_Int destroy ) 81*37da2899SCharles.Forsyth { 82*37da2899SCharles.Forsyth FT_CleanupItem top; 83*37da2899SCharles.Forsyth 84*37da2899SCharles.Forsyth 85*37da2899SCharles.Forsyth FT_ASSERT( stack && stack->chunk && stack->top ); 86*37da2899SCharles.Forsyth top = stack->top; 87*37da2899SCharles.Forsyth 88*37da2899SCharles.Forsyth if ( top == stack->chunk->items ) 89*37da2899SCharles.Forsyth { 90*37da2899SCharles.Forsyth FT_CleanupChunk chunk; 91*37da2899SCharles.Forsyth 92*37da2899SCharles.Forsyth chunk = stack->chunk; 93*37da2899SCharles.Forsyth 94*37da2899SCharles.Forsyth if ( chunk == &stack->chunk_0 ) 95*37da2899SCharles.Forsyth { 96*37da2899SCharles.Forsyth FT_ERROR(( "cleanup.pop: empty cleanup stack !!\n" )); 97*37da2899SCharles.Forsyth ft_cleanup_throw( stack, FT_Err_EmptyCleanupStack ); 98*37da2899SCharles.Forsyth } 99*37da2899SCharles.Forsyth 100*37da2899SCharles.Forsyth chunk = chunk->link; 101*37da2899SCharles.Forsyth FT_QFree( stack->chunk, stack->memory ); 102*37da2899SCharles.Forsyth 103*37da2899SCharles.Forsyth stack->chunk = chunk; 104*37da2899SCharles.Forsyth stack->limit = chunk->items + FT_CLEANUP_CHUNK_SIZE; 105*37da2899SCharles.Forsyth top = stack->limit; 106*37da2899SCharles.Forsyth } 107*37da2899SCharles.Forsyth 108*37da2899SCharles.Forsyth top --; 109*37da2899SCharles.Forsyth 110*37da2899SCharles.Forsyth if ( destroy ) 111*37da2899SCharles.Forsyth top->item_func( top->item, top->item_data ); 112*37da2899SCharles.Forsyth 113*37da2899SCharles.Forsyth top->item = NULL; 114*37da2899SCharles.Forsyth top->item_func = NULL; 115*37da2899SCharles.Forsyth top->item_data = NULL; 116*37da2899SCharles.Forsyth 117*37da2899SCharles.Forsyth stack->top = top; 118*37da2899SCharles.Forsyth } 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth 121*37da2899SCharles.Forsyth 122*37da2899SCharles.Forsyth FT_BASE_DEF( FT_CleanupItem ) ft_cleanup_stack_peek(FT_CleanupStack stack)123*37da2899SCharles.Forsyth ft_cleanup_stack_peek( FT_CleanupStack stack ) 124*37da2899SCharles.Forsyth { 125*37da2899SCharles.Forsyth FT_CleanupItem top; 126*37da2899SCharles.Forsyth FT_CleanupChunk chunk; 127*37da2899SCharles.Forsyth 128*37da2899SCharles.Forsyth 129*37da2899SCharles.Forsyth FT_ASSERT( stack && stack->chunk && stack->top ); 130*37da2899SCharles.Forsyth 131*37da2899SCharles.Forsyth top = stack->top; 132*37da2899SCharles.Forsyth chunk = stack->chunk; 133*37da2899SCharles.Forsyth 134*37da2899SCharles.Forsyth if ( top > chunk->items ) 135*37da2899SCharles.Forsyth top--; 136*37da2899SCharles.Forsyth else 137*37da2899SCharles.Forsyth { 138*37da2899SCharles.Forsyth chunk = chunk->link; 139*37da2899SCharles.Forsyth top = NULL; 140*37da2899SCharles.Forsyth if ( chunk != NULL ) 141*37da2899SCharles.Forsyth top = chunk->items + FT_CLEANUP_CHUNK_SIZE - 1; 142*37da2899SCharles.Forsyth } 143*37da2899SCharles.Forsyth return top; 144*37da2899SCharles.Forsyth } 145*37da2899SCharles.Forsyth 146*37da2899SCharles.Forsyth 147*37da2899SCharles.Forsyth 148*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_xhandler_enter(FT_XHandler xhandler,FT_Memory memory)149*37da2899SCharles.Forsyth ft_xhandler_enter( FT_XHandler xhandler, 150*37da2899SCharles.Forsyth FT_Memory memory ) 151*37da2899SCharles.Forsyth { 152*37da2899SCharles.Forsyth FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); 153*37da2899SCharles.Forsyth 154*37da2899SCharles.Forsyth xhandler->previous = stack->xhandler; 155*37da2899SCharles.Forsyth xhandler->cleanup = stack->top; 156*37da2899SCharles.Forsyth xhandler->error = 0; 157*37da2899SCharles.Forsyth stack->xhandler = xhandler; 158*37da2899SCharles.Forsyth } 159*37da2899SCharles.Forsyth 160*37da2899SCharles.Forsyth 161*37da2899SCharles.Forsyth 162*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_xhandler_exit(FT_XHandler xhandler)163*37da2899SCharles.Forsyth ft_xhandler_exit( FT_XHandler xhandler ) 164*37da2899SCharles.Forsyth { 165*37da2899SCharles.Forsyth FT_CleanupStack stack = FT_MEMORY__CLEANUP(memory); 166*37da2899SCharles.Forsyth 167*37da2899SCharles.Forsyth stack->xhandler = xhandler->previous; 168*37da2899SCharles.Forsyth xhandler->previous = NULL; 169*37da2899SCharles.Forsyth xhandler->error = error; 170*37da2899SCharles.Forsyth xhandler->cleanup = NULL; 171*37da2899SCharles.Forsyth } 172*37da2899SCharles.Forsyth 173*37da2899SCharles.Forsyth 174*37da2899SCharles.Forsyth 175*37da2899SCharles.Forsyth FT_BASE_DEF( void ) ft_cleanup_throw(FT_CleanupStack stack,FT_Error error)176*37da2899SCharles.Forsyth ft_cleanup_throw( FT_CleanupStack stack, 177*37da2899SCharles.Forsyth FT_Error error ) 178*37da2899SCharles.Forsyth { 179*37da2899SCharles.Forsyth FT_XHandler xhandler = stack->xhandler; 180*37da2899SCharles.Forsyth 181*37da2899SCharles.Forsyth if ( xhandler == NULL ) 182*37da2899SCharles.Forsyth { 183*37da2899SCharles.Forsyth /* no exception handler was registered. this */ 184*37da2899SCharles.Forsyth /* means that we have an un-handled exception */ 185*37da2899SCharles.Forsyth /* the only thing we can do is _PANIC_ and */ 186*37da2899SCharles.Forsyth /* halt the current program.. */ 187*37da2899SCharles.Forsyth /* */ 188*37da2899SCharles.Forsyth FT_ERROR(( "FREETYPE PANIC: An un-handled exception occured. Program aborted" )); 189*37da2899SCharles.Forsyth ft_exit(1); 190*37da2899SCharles.Forsyth } 191*37da2899SCharles.Forsyth 192*37da2899SCharles.Forsyth /* cleanup the stack until we reach the handler's */ 193*37da2899SCharles.Forsyth /* starting stack location.. */ 194*37da2899SCharles.Forsyth 195*37da2899SCharles.Forsyth xhandler->error = error; 196*37da2899SCharles.Forsyth longmp( xhandler->jump_buffer, 1 ); 197*37da2899SCharles.Forsyth }