pike.git / src / builtin.cmod

version» Context lines:

pike.git/src/builtin.cmod:6643:    return;    }    Pike_error("Stack underflow\n");    }       /*! @decl mixed pop(void|int val)    *! Pops and returns entry @[val] from the stack, counting    *! from the top. If no value is given the top element is    *! popped and returned. All popped entries are freed from    *! the stack. +  *! +  *! @seealso +  *! @[quick_pop()], @[pop_to()]    */    PIKEFUN mixed pop(void|int val)    {    if (!THIS->arr || !THIS->arr->size) {    Pike_error("Stack underflow\n");    }       if (val && (val->u.integer > 0)) {    ptrdiff_t new_size;    ptrdiff_t old_size;       new_size = THIS->arr->size - val->u.integer;    if (new_size < 0) new_size = 0;       /* NB: Steal reference from the array element. */    *Pike_sp = ITEM(THIS->arr)[new_size];    old_size = THIS->arr->size;    THIS->arr->size = new_size;    Pike_sp++;    -  +  /* NB: +1 to skip freeing the returned element. */    free_svalues(ITEM(THIS->arr) + new_size + 1, old_size - (new_size + 1),    THIS->arr->type_field);    } else {    /* NB: Steal reference from the array element. */    THIS->arr->size--;    *Pike_sp = ITEM(THIS->arr)[THIS->arr->size];    Pike_sp++;    }    }       /*! @decl void quick_pop(void|int val)    *! Pops @[val] entries from the stack, or one entry    *! if no value is given. The popped entries are not    *! returned. -  +  *! +  *! @seealso +  *! @[pop()], @[pop_to()]    */    PIKEFUN void quick_pop(void|int val)    {    apply_current(f_Stack_pop_fun_num, args);    push_int(0);    }    -  +  /*! @decl void pop_to(int depth) +  *! +  *! Pops entries from the stack until it reaches the specified depth. +  *! +  *! The popped entries are not returned. +  *! +  *! @throws +  *! Throws an error if there are fewer than @[depth] elements +  *! on the stack. +  *! +  *! @seealso +  *! @[pop()], @[quick_pop()] +  */ +  PIKEFUN void pop_to(int depth) +  { +  ptrdiff_t old_size; +  +  if (!THIS->arr) { +  if (!depth) return; +  Pike_error("Stack underflow.\n"); +  } +  +  if ((depth < 0) || (THIS->arr->size < depth)) { +  Pike_error("Stack underflow.\n"); +  } +  +  old_size = THIS->arr->size; +  if (old_size == depth) return; /* NOOP */ +  +  if (!depth) { /* Pop all. */ +  free_array(THIS->arr); +  THIS->arr = NULL; +  return; +  } +  +  THIS->arr->size = depth; +  +  free_svalues(ITEM(THIS->arr) + depth, old_size - depth, +  THIS->arr->type_field); +  } +     /*! @decl void reset(int|void initial_size)    *! Empties the stack, resets the stack pointer    *! and shrinks the stack size to the given value    *! or 32 if none is given.    *! @seealso    *! @[create]    */    PIKEFUN void reset(int|void initial_size)    {    ptrdiff_t size = 32;