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

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