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

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