]> git.llucax.com Git - z.facultad/75.42/calculadora.git/blob - dllist.c
Últimos retoques.
[z.facultad/75.42/calculadora.git] / dllist.c
1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 2:
6  * Programa calculadora.
7  *
8  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9  * Puede copiar, modificar y distribuir este programa bajo los términos de
10  * la licencia GPL (http://www.gnu.org/).
11  *
12  * Creado: sáb ago 30 20:34:45 ART 2003
13  *
14  * $Id$
15  */
16
17 #include "dllist.h"
18 /* Para usar NULL, malloc() y free(). */
19 #include <stdlib.h>
20
21 DLList* DLList_new(void) {
22     /* Aloco memoria para la lista. */
23     DLList* list = (DLList*)malloc(sizeof(DLList));
24     /* Si la obtuve, inicializo todo a NULL. */
25     if (list) {
26         list->first   = NULL;
27         list->current = NULL;
28         list->last    = NULL;
29     }
30     /* Devuelvo el nuevo puntero. */
31     return list;
32 }
33
34 void DLList_delete(DLList* list) {
35     /* Si el puntero a la lista no es NULL. */
36     if (list) {
37         /* Elimino los nodos. */
38         while (!DLList_empty(list)) {
39             DLList_pop(list);
40         }
41     }
42     /* Libero memoria de la lista. */
43     free(list);
44 }
45
46 bool DLList_empty(DLList* list) {
47     return list->first == NULL;
48 }
49
50 void* DLList_begin(DLList* list) {
51     list->current = list->first;
52     /* Si hay un nodo, devulevo sus datos, si no NULL. */
53     return list->current ? list->current->data : NULL;
54 }
55
56 void* DLList_end(DLList* list) {
57     list->current = list->last;
58     /* Si hay un nodo, devulevo sus datos, si no NULL. */
59     return list->current ? list->current->data : NULL;
60 }
61
62 bool DLList_have_more(DLList* list) {
63     return list->current != NULL;
64 }
65
66 void* DLList_current(DLList* list) {
67     return list->current ? list->current->data : NULL;
68 }
69
70 void* DLList_next(DLList* list) {
71     DLNode* current = list->current;
72     /* Si no está vacía ni ya fue terminada de recorrer. */
73     if (current) {
74         /* Apuntamos el actual al próximo. */
75         list->current = current->next;
76         /* Devolvemos los datos del próximo o NULL si no había otro. */
77         return list->current ? list->current->data : NULL;
78     /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
79     } else {
80         return NULL;
81     }
82 }
83
84 void* DLList_prev(DLList* list) {
85     DLNode* current = list->current;
86     /* Si no está vacía ni ya fue terminada de recorrer. */
87     if (current) {
88         /* Apuntamos el actual al anterior. */
89         list->current = current->prev;
90         /* Devolvemos los datos del anterior o NULL si no había otro. */
91         return list->current ? list->current->data : NULL;
92     /* Si está vacía o ya fue terminada de recorrer devolvemos NULL. */
93     } else {
94         return NULL;
95     }
96 }
97
98 bool DLList_unshift(DLList* list, void* data) {
99     DLNode* node = (DLNode*)malloc(sizeof(DLNode));
100     /* Si obtenemos la memoria bien, actualizamos lo que sea necesario. */
101     if (node) {
102         /* Inicializamos el nuevo nodo. */
103         node->prev = NULL;
104         node->data = data;
105         node->next = list->first;
106         /* Apunto el nodo actual al nuevo nodo. */
107         list->current = node;
108         /* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
109         if (list->first == NULL) {
110             list->first = node;
111             list->last  = node;
112         /* Si no está vacía. */
113         } else {
114             /* Apunto el nodo anterior al primer nodo de la lista al nuevo. */
115             list->first->prev = node;
116             /* Apunto el primer nodo de la lista al nuevo. */
117             list->first = node;
118         }
119     }
120     return node ? TRUE : FALSE;
121 }
122
123 bool DLList_push(DLList* list, void* data) {
124     DLNode* node = (DLNode*)malloc(sizeof(DLNode));
125     /* Si obtenemos la memoria bien, actualizamos lo que sea necesario. */
126     if (node) {
127         /* Inicializamos el nuevo nodo. */
128         node->prev = list->last;
129         node->data = data;
130         node->next = NULL;
131         /* Apunto el nodo actual al nuevo nodo. */
132         list->current = node;
133         /* Si la lista está vacía hay que hacer apuntar todo al nuevo nodo. */
134         if (list->first == NULL) {
135             list->first = node;
136             list->last  = node;
137         /* Si no está vacía. */
138         } else {
139             /* Apunto el próximo nodo del último nodo de la lista al nuevo. */
140             list->last->next = node;
141             /* Apunto el último nodo de la lista al nuevo. */
142             list->last = node;
143         }
144     }
145     return node ? TRUE : FALSE;
146 }
147
148 void* DLList_shift(DLList* list) {
149     /* Primer nodo */
150     DLNode* node = list->first;
151     /* Datos del primer nodo. */
152     void* data = node->data;
153     /* Pongo como primer nodo al siguiente. */
154     list->first = node->next;
155     /* Pongo al primero como nodo actual. */
156     list->current = list->first;
157     /* Si era el único pongo el último en NULL. */
158     if (!list->first) {
159         list->last = NULL;
160     /* Si no, pongo el anterior en NULL. */
161     } else {
162         list->first->prev = NULL;
163     }
164     /* Libero memoria del nodo. */
165     free(node);
166     return data;
167 }
168
169 void* DLList_pop(DLList* list) {
170     /* Último nodo */
171     DLNode* node = list->last;
172     /* Datos del último nodo. */
173     void* data = node->data;
174     /* Pongo como último nodo al anterior. */
175     list->last = node->prev;
176     /* Pongo al último como nodo actual. */
177     list->current = list->last;
178     /* Si era el único pongo el primero en NULL. */
179     if (!list->last) {
180         list->first = NULL;
181     /* Si no, pongo el siguiente en NULL. */
182     } else {
183         list->last->next = NULL;
184     }
185     /* Libero memoria del nodo. */
186     free(node);
187     return data;
188 }
189
190 void* DLList_remove_current(DLList* list) {
191     /* Nodo actual */
192     DLNode* current = list->current;
193     /* Datos del nodo actual. */
194     void* data = current->data;
195     /* Si tiene siguiente. */
196     if (current->next) {
197         /* Se pone como anterior del siguiente al anterior del actual. */
198         current->next->prev = current->prev;
199     /* Si no tiene siguiente, se pone como último al anterior del actual. */
200     } else {
201         list->last = current->prev;
202     }
203     /* Si tiene anterior. */
204     if (current->prev) {
205         /* Se pone como siguiente del anterior al siguiente del actual. */
206         current->prev->next = current->next;
207     /* Si no tiene anterior, se pone como primero al siguiente del actual. */
208     } else {
209         list->first = current->next;
210     }
211     /* Pongo como elemento actual al próximo elemento. */
212     list->current = current->next;
213     /* Libero memoria del nodo. */
214     free(current);
215     return data;
216 }
217