stack.c (2183B)
1 2 #include "stack.h" 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <string.h> 6 7 void 8 stack_clear(struct stack *stack) { 9 memset(stack->bottom, 0, stack->capacity); 10 stack->top = stack->bottom; 11 } 12 13 int 14 stack_init_size(struct stack *stack, int capacity) { 15 if (capacity > DEFAULT_STACK_SIZE) { 16 void *bottom = calloc(capacity, sizeof(void*)); 17 if (!bottom) return 0; 18 stack->bottom = bottom; 19 stack->top = bottom; 20 stack->capacity = capacity; 21 } 22 else { 23 stack->bottom = stack->_data; 24 stack->top = stack->bottom; 25 stack->capacity = DEFAULT_STACK_SIZE; 26 } 27 stack_clear(stack); 28 return 1; 29 } 30 31 int 32 stack_init(struct stack *stack) { 33 return stack_init_size(stack, DEFAULT_STACK_SIZE); 34 } 35 36 void 37 stack_free(struct stack *stack) { 38 if (stack->capacity > DEFAULT_STACK_SIZE) 39 free(stack->bottom); 40 stack->bottom = stack->_data; 41 } 42 43 44 int 45 stack_expand(struct stack *stack) { 46 size_t newcap = stack->capacity * 2; 47 void **bottom = 0; 48 int size = stack_size(stack); 49 50 #if DEBUG 51 printf("expanding s(%d) %d -> %d\n", size, stack->capacity, newcap); 52 #endif 53 54 // XXX: might want to relax this to <= eventually 55 assert(size == stack->capacity); 56 57 if (stack->capacity <= DEFAULT_STACK_SIZE) { 58 bottom = malloc(newcap * sizeof(void*)); 59 if (!bottom) return 0; 60 memcpy(bottom, stack->bottom, size * sizeof(void*)); 61 } 62 else { 63 bottom = realloc(stack->bottom, newcap * sizeof(void*)); 64 if (!bottom) return 0; 65 } 66 stack->capacity = newcap; 67 stack->bottom = bottom; 68 stack->top = bottom+size; 69 return 1; 70 } 71 72 void 73 stack_push(struct stack *stack, void *val) { 74 #if 0 75 printf("pushing: %d %p\n", stack_size(stack), val); 76 #endif 77 78 if ((stack_size(stack) + 1) > stack->capacity) { 79 stack_expand(stack); 80 } 81 82 *stack->top++ = val; 83 } 84 85 void 86 stack_erase(struct stack *stack, int pos) { 87 if (stack_size(stack) == 0) return; 88 size_t len = stack->top - (stack->top + pos); 89 memcpy(stack->top + pos, stack->top + pos + 1, sizeof(stack->top) * len); 90 stack->top--; 91 } 92 93 void * 94 stack_pop(struct stack *stack) { 95 assert(stack); 96 assert(stack_size(stack) != 0); 97 void * v = stack_top(stack, -1); 98 stack->top--; 99 return v; 100 } 101