diff --git a/src/passbook.c b/src/passbook.c
index 71a7d155eb4b997c37ba440ee54ac3cfc63dade8..d42c1e6d67e6e8913f8f5017933ba2b6434faea5 100644
--- a/src/passbook.c
+++ b/src/passbook.c
@@ -192,12 +192,14 @@ char inst[INSTRUCTION_LENGTH];
/* password mapping for each url: initially empty */
node_t * map = NULL;
-/* a list of node pointers -- the idea is to use these to implement a node
- stack that we can then use to traverse the tree iteratively, avoiding
- recursion. We need tree traversal e.g. when saving the passbook to a file */
+/* a doubly-linked list of node pointers
+ is used to implement stacks/queues of nodes so we can implement various
+ tree traversal algorithms without using recursion (to avoid stack overflow
+ for very large trees). */
typedef struct nodeptr_list {
const node_t *p;
struct nodeptr_list *next;
+ struct nodeptr_list *prev;
} nodeptr_list_t;
@@ -206,26 +208,47 @@ nodeptr_list_t * list_push(nodeptr_list_t *lst, const node_t *p){
assert(n != NULL && "push: malloc failed");
n->p = p;
n->next = lst;
+ if (lst != NULL){
+ lst->prev = n;
+ }
+ n->prev = NULL;
return n;
}
+/* when out is non-NULL we place a pointer to the first node into it */
+nodeptr_list_t * list_pop(nodeptr_list_t *lst, const node_t **out){
+ if (lst != NULL){
+ if (out != NULL){
+ *out = lst->p;
+ }
+ nodeptr_list_t *ret = lst->next;
+ free(lst);
+ return ret;
+ }else{
+ if (out != NULL){
+ *out = (const node_t *)NULL;
+ }
+ return lst;
+ }
+}
+
void list_destroy(nodeptr_list_t *lst){
while (lst != NULL){
- nodeptr_list_t *next = lst->next;
- free(lst);
- lst = next;
+ lst = list_pop(lst,NULL);
}
}
void list_print(nodeptr_list_t *lst){
printf("\nBegin list print:\n");
while (lst != NULL){
- node_print(lst->p);
- lst = lst->next;
+ const node_t *p;
+ lst = list_pop(lst,&p);
+ node_print(p);
}
printf("End list print.\n\n");
}
+
void print_all(const node_t *p){
nodeptr_list_t *lst = NULL;
if (p != NULL){
@@ -239,10 +262,8 @@ void print_all(const node_t *p){
}
// pop from the stack to simulate the return
- const node_t *q = lst->p;
- nodeptr_list_t *temp = lst;
- lst = lst->next;
- free(temp);
+ const node_t *q;
+ lst = list_pop(lst,&q);
// print the node following the return
node_print(q);