pike.git
/
src
/
builtin.cmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/builtin.cmod:1:
/* -*- c -*- || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
-
|| $Id: builtin.cmod,v 1.
169
2004/09/
15
08
:
08
:
42
grubba Exp $
+
|| $Id: builtin.cmod,v 1.
170
2004/09/
17
15:
07
:
43
grubba Exp $
*/ #include "global.h" #include "interpret.h" #include "svalue.h" #include "pike_macros.h" #include "object.h" #include "program.h" #include "array.h" #include "pike_error.h"
pike.git/src/builtin.cmod:3065:
*! *! Linked list of values. */ PIKECLASS List { CVAR struct list_node *head; CVAR INT32 head_sentinel_refs; CVAR struct list_node *tail; /* Always NULL. */ CVAR INT32 tail_sentinel_refs; CVAR struct list_node *tail_pred;
+
CVAR INT32 num_elems;
#define HEAD_SENTINEL(this) ((struct list_node *)(&this->head)) #define TAIL_SENTINEL(this) ((struct list_node *)(&this->tail)) /* Sentinel overlap description: * * List Head sentinel Tail sentinel * head next * head_sentinel_refs refs * tail prev next
pike.git/src/builtin.cmod:3099:
* o Support for reverse(), filter() and map(). * o Initialization from array. */ INIT { THIS->tail = NULL; THIS->head = TAIL_SENTINEL(THIS); THIS->tail_pred = HEAD_SENTINEL(THIS); THIS->head_sentinel_refs = THIS->tail_sentinel_refs = 2;
+
THIS->num_elems = 0;
} EXIT { struct list_node *node = THIS->head; struct list_node *next; while ((next = node->next)) { #ifdef PIKE_DEBUG if (node->refs != 2) { Pike_fatal("Unexpected number of references for node: %d\n",
pike.git/src/builtin.cmod:3175:
*! *! @returns *! Returns @expr{1@} if the list is empty, *! and @expr{0@} (zero) if there are elements in the list. */ PIKEFUN int(0..1) is_empty() { push_int(!THIS->head->next); }
+
/*! @decl int(0..) _sizeof()
+
*!
+
*! Returns the number of elements in the list.
+
*/
+
PIKEFUN int(0..) _sizeof()
+
flags ID_STATIC;
+
{
+
push_int(THIS->num_elems);
+
}
+
/*! @decl mixed head() *! *! Get the element at the head of the list. *! *! @throws *! Throws an error if the list is empty. *! *! @seealso *! @[is_empty()], @[tail()], @[pop()] */
pike.git/src/builtin.cmod:3232:
*/ PIKEFUN mixed pop() { if (THIS->head->next) { push_svalue(&THIS->head->val); if (THIS->head->refs == 2) { unlink_list_node(THIS->head); } else { detach_list_node(THIS->head); }
+
THIS->num_elems--;
} else { Pike_error("Empty list.\n"); } } /*! @decl void append(mixed ... values) *! *! Append @[values] to the end of the list. *! *! @seealso *! @[insert()] */ PIKEFUN void append(mixed ... values) { struct list_node *node = TAIL_SENTINEL(THIS); while (args--) { struct list_node *new = alloc_list_node(); new->val = *(--Pike_sp); prepend_list_node(node, new); free_list_node(node = new);
-
+
THIS->num_elems++;
} push_int(0); } /*! @decl void insert(mixed ... values) *! *! Insert @[values] at the front of the list. *! *! @seealso *! @[append()] */ PIKEFUN void insert(mixed ... values) { struct list_node *node = THIS->head; while (args--) { struct list_node *new = alloc_list_node(); new->val = *(--Pike_sp); prepend_list_node(node, new); free_list_node(node = new);
-
+
THIS->num_elems++;
} push_int(0); } /*! @decl void create(mixed ... values) *! *! Create a new @[List], and initialize it with @[values]. *! *! @fixme *! Ought to reset the @[List] if called multiple times.
pike.git/src/builtin.cmod:3304:
program_flags PROGRAM_USES_PARENT; flags ID_STATIC; { CVAR struct list_node *cur; CVAR INT32 ind; /* Not meaningful, but requred by the API. */ /* NOTE: cur may never refer to an unlinked node. * cur may however refer to a detached node, or to sentinels. */
-
INIT
+
static struct List_struct *List__get_iterator_find_parent()
{ struct external_variable_context loc;
-
struct List_struct *parent;
+
-
/* Find our parent. */
+
loc.o = Pike_fp->current_object; loc.parent_identifier = Pike_fp->fun; loc.inherit = INHERIT_FROM_INT(loc.o->prog, loc.parent_identifier); find_external_context(&loc, 1);
-
parent
=
(struct List_struct *)(loc.o->storage +
+
return
(struct List_struct *)(loc.o->storage +
loc.inherit->storage_offset);
-
add_ref(THIS->cur = parent->head);
+
}
+
+
INIT
+
{
+
add_ref(THIS->cur =
List__get_iterator_find_
parent
()
->head);
THIS->ind = 0; } EXIT { if (THIS->cur) { free_list_node(THIS->cur); THIS->cur = NULL; } }
pike.git/src/builtin.cmod:3607:
{ struct list_node *new; if (!THIS->cur->prev) { Pike_error("Attempt to insert before the start sentinel.\n"); } new = alloc_list_node(); assign_svalue_no_free(&new->val, val); prepend_list_node(THIS->cur, new); free_list_node(THIS->cur); THIS->cur = new;
+
List__get_iterator_find_parent()->num_elems++;
pop_n_elems(args); push_int(0); } /*! @decl void append(mixed val) *! *! Append @[val] after the current position. *! *! @seealso *! @[insert()], @[delete()], @[set()]
pike.git/src/builtin.cmod:3628:
PIKEFUN void append(mixed val) { struct list_node *new; if (!THIS->cur->next) { Pike_error("Attempt to append after the end sentinel.\n"); } new = alloc_list_node(); assign_svalue_no_free(&new->val, val); append_list_node(THIS->cur, new); free_list_node(new);
+
List__get_iterator_find_parent()->num_elems++;
pop_n_elems(args); push_int(0); } /*! @decl void delete() *! *! Delete the current node. *! *! The current position will advance to the next node. *! This function thus performes the reverse operation
pike.git/src/builtin.cmod:3650:
*! @seealso *! @[insert()], @[append()], @[set()] */ PIKEFUN void delete() { struct list_node *next; if (!(next = THIS->cur->next) || !THIS->cur->prev) { Pike_error("Attempt to delete a sentinel.\n"); } add_ref(next);
+
if (next->prev == THIS->cur) {
if (THIS->cur->refs == 3) { unlink_list_node(THIS->cur); } else { /* There's some other iterator holding references to this node. */ detach_list_node(THIS->cur); }
-
+
List__get_iterator_find_parent()->num_elems--;
+
}
free_list_node(THIS->cur); THIS->cur = next; pop_n_elems(args); push_int(0); } /*! @decl void set(mixed val) *! *! Set the value of the current position to @[val]. *!