source: trunk/athena/bin/aklog/linked_list.c @ 10763

Revision 10763, 4.2 KB checked in by ghudson, 27 years ago (diff)
ANSIfy a bit.
Line 
1/*
2 * $Id: linked_list.c,v 1.5 1997-11-17 16:23:50 ghudson Exp $
3 *
4 * This file contains general linked list routines.
5 *
6 * Copyright 1990,1991 by the Massachusetts Institute of Technology
7 * For distribution and copying rights, see the file "mit-copyright.h"
8 */
9
10static const char rcsid[] = "$Id: linked_list.c,v 1.5 1997-11-17 16:23:50 ghudson Exp $";
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "linked_list.h"
16
17#ifndef NULL
18#define NULL 0
19#endif
20
21#ifndef TRUE
22#define TRUE 1
23#endif
24
25#ifndef FALSE
26#define FALSE 0
27#endif
28
29void ll_init(linked_list *list)
30  /*
31   * Requires:
32   *   List must point to a linked list structure.  It is not acceptable
33   *   to pass a null pointer to this routine.
34   * Modifies:
35   *   list
36   * Effects:
37   *   Initializes the list to be one with no elements.  If list is
38   *   NULL, prints an error message and causes the program to crash.
39   */
40{
41    if (list == NULL) {
42        fprintf(stderr, "Error: calling ll_init with null pointer.\n");
43        abort();
44    }
45
46    /* This sets everything to zero, which is what we want. */
47    memset(list, 0, sizeof(linked_list));
48}
49
50ll_node *ll_add_node(linked_list *list, ll_end which_end)
51  /*
52   * Modifies:
53   *   list
54   * Effects:
55   *   Adds a node to one end of the list (as specified by which_end)
56   *   and returns a pointer to the node added.  which_end is of type
57   *   ll_end and should be either ll_head or ll_tail as specified in
58   *   list.h.  If there is not enough memory to allocate a node,
59   *   the program returns NULL.
60   */
61{
62    ll_node *node = NULL;
63   
64    if ((node = (ll_node *)calloc(1, sizeof(ll_node))) != NULL) {
65        if (list->nelements == 0) {
66            list->first = node;
67            list->last = node;
68            list->nelements = 1;
69        }
70        else {
71            switch (which_end) {
72              case ll_head:
73                list->first->prev = node;
74                node->next = list->first;
75                list->first = node;
76                break;
77              case ll_tail:
78                list->last->next = node;
79                node->prev = list->last;
80                list->last = node;
81                break;
82              default:
83                fprintf(stderr, "%s%s",
84                        "ll_add_node got a which_end parameter that ",
85                        "it can't handle.\n");
86                abort();
87            }
88            list->nelements++;
89        }
90    }
91       
92    return(node);
93}
94
95
96int ll_delete_node(linked_list *list, ll_node *node)
97  /*
98   * Modifies:
99   *   list
100   * Effects:
101   *   If node is in list, deletes node and returns LL_SUCCESS. 
102   *   Otherwise, returns LL_FAILURE.  If node contains other data,
103   *   it is the responsibility of the caller to free it.  Also, since
104   *   this routine frees node, after the routine is called, "node"
105   *   won't point to valid data.
106   */
107{
108    int status = LL_SUCCESS;
109    ll_node *cur_node = NULL;
110    int found = FALSE;
111
112    if (list->nelements == 0)
113        status = LL_FAILURE;
114    else {
115        for (cur_node = list->first; (cur_node != NULL) && !found;
116             cur_node = cur_node->next) {
117            if (cur_node == node) {
118
119                if (cur_node->prev)
120                    cur_node->prev->next = cur_node->next;
121                else
122                    list->first = cur_node->next;
123
124                if (cur_node->next)
125                    cur_node->next->prev = cur_node->prev;
126                else
127                    list->last = cur_node->prev;
128
129                free(cur_node);
130                list->nelements--;
131                found = TRUE;
132            }
133        }
134    }
135
136    if (!found)
137        status = LL_FAILURE;
138
139    return(status);
140}
141
142
143/* ll_add_data is a macro defined in linked_list.h */
144
145/* This routine maintains a list of strings preventing duplication. */
146int ll_string(linked_list *list, ll_s_action action, char *string)
147{
148    int status = LL_SUCCESS;
149    ll_node *cur_node;
150
151    switch(action) {
152      case ll_s_check:
153        /* Scan the list until we find the string in question */
154        for (cur_node = list->first; cur_node && (status == FALSE);
155             cur_node = cur_node->next)
156            status = (strcmp(string, cur_node->data) == 0);
157        break;
158      case ll_s_add:
159        /* Add a string to the list. */
160        if (!ll_string(list, ll_s_check, string)) {
161            if (cur_node = ll_add_node(list, ll_tail)) {
162                char *new_string;
163                if (new_string = (char *)calloc(strlen(string) + 1,
164                                                sizeof(char))) {
165                    strcpy(new_string, string);
166                    ll_add_data(cur_node, new_string);
167                }
168                else
169                    status = LL_FAILURE;
170            }
171            else
172                status = LL_FAILURE;
173        }
174        break;
175      default:
176        /* This should never happen */
177        status = LL_FAILURE;
178        break;
179    }
180
181    return(status);
182}
Note: See TracBrowser for help on using the repository browser.