btcs

bitcoin script parser/evaluator/compiler/decompiler
git clone git://jb55.com/btcs
Log | Files | Refs | README | LICENSE

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