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