1 /* vim: set et sts=4 sw=4 fdm=indent fdl=1 fdn=0 fo+=t tw=80:
3 * Taller de Programación (75.42).
6 * Programa calculadora.
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/).
12 * Creado: sáb ago 30 20:34:45 ART 2003
18 /* Para usar NULL, malloc() y free(). */
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. */
30 /* Devuelvo el nuevo puntero. */
34 void DLList_delete(DLList* list) {
35 /* Si el puntero a la lista no es NULL. */
37 /* Elimino los nodos. */
38 while (!DLList_empty(list)) {
41 /* Libero memoria de la lista. */
46 bool DLList_empty(DLList* list) {
47 return list->first == NULL;
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;
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;
62 bool DLList_have_more(DLList* list) {
63 return list->current != NULL;
66 void* DLList_current(DLList* list) {
67 return list->current ? list->current->data : NULL;
70 void* DLList_next(DLList* list) {
71 DLNode* current = list->current;
72 /* Si no está vacía ni ya fue terminada de recorrer. */
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. */
84 void* DLList_prev(DLList* list) {
85 DLNode* current = list->current;
86 /* Si no está vacía ni ya fue terminada de recorrer. */
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. */
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. */
102 /* Inicializamos el nuevo nodo. */
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) {
112 /* Si no está vacía. */
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. */
120 return node ? TRUE : FALSE;
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. */
127 /* Inicializamos el nuevo nodo. */
128 node->prev = list->last;
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) {
137 /* Si no está vacía. */
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. */
145 return node ? TRUE : FALSE;
148 void* DLList_shift(DLList* list) {
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. */
160 /* Si no, pongo el anterior en NULL. */
162 list->first->prev = NULL;
164 /* Libero memoria del nodo. */
169 void* DLList_pop(DLList* list) {
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. */
181 /* Si no, pongo el siguiente en NULL. */
183 list->last->next = NULL;
185 /* Libero memoria del nodo. */
190 void* DLList_remove_current(DLList* list) {
192 DLNode* current = list->current;
193 /* Datos del nodo actual. */
194 void* data = current->data;
195 /* Si tiene siguiente. */
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. */
201 list->last = current->prev;
203 /* Si tiene anterior. */
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. */
209 list->first = current->next;
211 /* Pongo como elemento actual al próximo elemento. */
212 list->current = current->next;
213 /* Libero memoria del nodo. */