Appendix H - linked_list.c
1:  #include < string.h >
2:  #include "bool.h"
3:  #include "linked_list.h"
4:  
5:  void InitList(list_info* list_pointers)
6:  {
7:    (*list_pointers).head = NULL;
8:    (*list_pointers).cur  = NULL;
9:    (*list_pointers).tail = NULL;
10:  }
11:  
12:  void FreeList(list_info* list_pointers)
13:  {
14:    ToFirst(list_pointers);
15:    while (!ListIsEmpty(list_pointers))
16:      Delete(list_pointers);
17:  }
18:  
19:  bool ListIsEmpty(list_info* list_pointers)
20:  {
21:    return ((*list_pointers).head == NULL ? TRUE : FALSE);
22:  }
23:  
24:  int Length(list_info* list_pointers)
25:  {
26:    list_info temp;
27:    int count = 0;
28:    
29:    memcpy(&temp, list_pointers, sizeof(list_info));
30:    while(RetrieveNextNode(&temp).cur)
31:    {
32:       count++;
33:       Advance(&temp);
34:    }
35:  
36:    return count;
37:  }
38:  
39:  bool ListIsFull()
40:  {
41:    return FALSE;
42:    /*
43:    struct linked_list* temp =
44:      (struct linked_list*)malloc(sizeof(struct linked_list));
45:    
46:      if(temp)*/ /*if there is memory, return false*/
47:    /*{
48:      free(temp);
49:      return FALSE;
50:    }
51:    return TRUE;*/
52:  }
53:  
54:  bool CurIsEmpty(list_info* list_pointers)
55:  {
56:    return ((*list_pointers).cur == NULL ? TRUE : FALSE);
57:  }
58:  
59:  struct linked_list* ToFirst(list_info* list_pointers)
60:  {
61:    (*list_pointers).cur = (*list_pointers).head;
62:  
63:    return (*list_pointers).head;
64:  }
65:  
66:  struct linked_list* ToEnd(list_info* list_pointers)
67:  {
68:    (*list_pointers).cur = (*list_pointers).tail;
69:  
70:    return (*list_pointers).tail;
71:  }
72:  
73:  bool AtFirst(list_info* list_pointers)
74:  {
75:    return ((*list_pointers).head == (*list_pointers).cur ? TRUE : FALSE);
76:  }
77:  
78:  bool AtEnd(list_info* list_pointers)
79:  {
80:    return ((*list_pointers).tail == (*list_pointers).cur ? TRUE : FALSE);
81:  }
82:  
83:  void Advance(list_info* list_pointers)
84:  {
85:    if (CurIsEmpty(list_pointers))
86:      NodeReferenceError();
87:    else
88:      (*list_pointers).cur = (*list_pointers).cur- >next;
89:  }
90:  
91:  void Retreat(list_info* list_pointers)
92:  {
93:    if(CurIsEmpty(list_pointers))
94:      NodeReferenceError();
95:    else
96:      (*list_pointers).cur = (*list_pointers).cur- >prev;
97:  }
98:  
99:  void InsertAfter(el_t e, list_info* list_pointers)
100:  {
101:    node_pointer target = MakeNode(e);
102:  
103:    if (ListIsEmpty(list_pointers))
104:    {
105:       (*list_pointers).head = target;
106:       (*list_pointers).cur  = target;
107:       (*list_pointers).tail = target;
108:    }
109:    else if (CurIsEmpty(list_pointers))
110:       NodeReferenceError();
111:    else if (AtEnd(list_pointers))
112:    {
113:      target- >prev = (*list_pointers).cur;
114:      (*list_pointers).cur- >next = target;
115:      (*list_pointers).tail = target;  /*set new tail*/
116:    }
117:    else
118:    {
119:      target- >next = (*list_pointers).cur- >next;
120:      target- >prev = (*list_pointers).cur;
121:      (*list_pointers).cur- >next- >prev = target;
122:      (*list_pointers).cur- >next = target;
123:    }
124:  }
125:  
126:  void Insert(el_t e, list_info* list_pointers)
127:  {
128:    node_pointer target = MakeNode(e);
129:  
130:    if (ListIsEmpty(list_pointers))		/* create one-element list */
131:    {
132:      (*list_pointers).head = target;
133:      (*list_pointers).cur  = target;
134:      (*list_pointers).tail = target;
135:    }
136:    else if (CurIsEmpty(list_pointers))	/* empty cur, nonempty list */
137:       NodeReferenceError();
138:    else if(AtFirst(list_pointers))		/* new head node */
139:    {
140:      target- >next               = (*list_pointers).cur;
141:      (*list_pointers).cur- >prev = target;
142:      (*list_pointers).head      = target;
143:    }
144:    else				/* insert between two nodes */
145:    {
146:      target- >next    = (*list_pointers).cur;
147:      target- >prev    = (*list_pointers).cur- >prev;
148:      (*list_pointers).cur- >prev- >next = target;
149:      (*list_pointers).cur- >prev       = target;
150:    }
151:  }
152:  
153:  void Delete(list_info* list_pointers)
154:  {
155:    node_pointer tmp;
156:  
157:    if (CurIsEmpty(list_pointers))        /* empty list*/
158:       NodeReferenceError();
159:    else if (AtFirst(list_pointers) && AtEnd(list_pointers)) /*one node exists */
160:    {
161:        DestroyNode((*list_pointers).cur);
162:        /*set the pointers to null*/
163:        memset(list_pointers, 0, sizeof(list_info));
164:    }
165:    else if (AtFirst(list_pointers))	/* delete head node */
166:    {
167:      tmp = (*list_pointers).cur;
168:      (*list_pointers).cur = (*list_pointers).cur- >next;
169:      (*list_pointers).cur- >prev = NULL;
170:      (*list_pointers).head = (*list_pointers).cur;
171:      DestroyNode(tmp);
172:    }
173:    else if (AtEnd(list_pointers))                    /* delete end node */
174:    {
175:      tmp = (*list_pointers).cur;
176:      (*list_pointers).cur = (*list_pointers).cur- >prev;
177:      (*list_pointers).cur- >next = NULL;
178:      (*list_pointers).tail = (*list_pointers).cur;
179:      DestroyNode(tmp);
180:    }
181:    else					/* delete middle node */
182:    {
183:      tmp = (*list_pointers).cur;
184:      (*list_pointers).cur- >prev- >next = (*list_pointers).cur- >next;
185:      (*list_pointers).cur- >next- >prev = (*list_pointers).cur- >prev;
186:      (*list_pointers).cur = (*list_pointers).cur- >next;
187:      DestroyNode(tmp);
188:    }
189:  }
190:  
191:  void StoreInfo(el_t e, list_info* list_pointers)
192:  {
193:     if(CurIsEmpty(list_pointers))
194:        NodeReferenceError();
195:     else
196:       /*There had better be enough room...*/
197:        memcpy(&(((*list_pointers).cur)- >data), &e, sizeof(void*)); 
198:  }
199:  
200:  el_t RetrieveInfo(list_info* list_pointers)
201:  {
202:    if(CurIsEmpty(list_pointers))
203:       NodeReferenceError();
204:  
205:    return (((*list_pointers).cur)- >data);
206:  }
207:  
208:  el_t RetrievePrevInfo(list_info* list_pointers)
209:  {
210:    if (CurIsEmpty(list_pointers))
211:       NodeReferenceError();
212:    if(AtFirst(list_pointers))   
213:       NodeReferenceError();
214:  
215:    return (((*list_pointers).cur)- >prev- >data);
216:  }
217:  
218:  list_info RetrievePrevNode(list_info* list_pointers)
219:  {
220:    list_info temp;
221:    memcpy(&temp, list_pointers, sizeof(list_info));
222:  
223:    if (CurIsEmpty(list_pointers))
224:       NodeReferenceError();
225:  
226:    temp.cur = ((*list_pointers).cur)- >prev;
227:  
228:    return temp;
229:  }
230:  
231:  
232:  el_t RetrieveNextInfo(list_info* list_pointers)
233:  {
234:    if (CurIsEmpty(list_pointers))
235:       NodeReferenceError();
236:    if(AtEnd(list_pointers))
237:      NodeReferenceError();
238:  
239:    return (((*list_pointers).cur)- >next- >data);
240:  }
241:  
242:  list_info RetrieveNextNode(list_info* list_pointers)
243:  {
244:    list_info temp;
245:    memcpy(&temp, list_pointers, sizeof(list_info));
246:  
247:    if (CurIsEmpty(list_pointers))
248:       NodeReferenceError();
249:  
250:    temp.cur = ((*list_pointers).cur)- >next;
251:  
252:    return temp;
253:  }
254:  
255:  node_pointer MakeNode(el_t e)
256:  {
257:    node_pointer p;
258:  
259:    if(ListIsFull())
260:    {
261:      printf("List is Full.  Exiting.\n");
262:      exit(1);
263:    }
264:  
265:  
266:   
267:  #ifdef __cplusplus
268:    p = new struct linked_list;
269:  #else
270:    p = (struct linked_list*) malloc(sizeof(struct linked_list));
271:  #endif
272:  
273:    if (!p)
274:    {
275:      printf("Error making node\n");
276:      exit(1);
277:    }
278:    else
279:    {
280:      memcpy(&(p- >data), &e, sizeof(el_t));
281:      p- >next = NULL;
282:      p- >prev = NULL;
283:    }
284:  
285:    return p;
286:  }
287:  
288:  void DestroyNode(node_pointer p)
289:  {
290:  #ifdef __cplusplus
291:    delete p;
292:  #else
293:    free(p);
294:  #endif
295:  }
296:  
297:  void NodeReferenceError()
298:  {
299:    int *temp = NULL;
300:    printf("ERROR: No current node or an improper node\n");
301:  printf("%d\n", *temp);
302:    exit(1);
303:  }
304:  
305:  
306: