Imported Upstream version 3.3.3
[debian/amanda] / common-src / am_sl.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * Copyright (c) 2007-2012 Zmanda, Inc.  All Rights Reserved.
5  * All Rights Reserved.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and its
8  * documentation for any purpose is hereby granted without fee, provided that
9  * the above copyright notice appear in all copies and that both that
10  * copyright notice and this permission notice appear in supporting
11  * documentation, and that the name of U.M. not be used in advertising or
12  * publicity pertaining to distribution of the software without specific,
13  * written prior permission.  U.M. makes no representations about the
14  * suitability of this software for any purpose.  It is provided "as is"
15  * without express or implied warranty.
16  *
17  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  *
24  * Author: James da Silva, Systems Design and Analysis Group
25  *                         Computer Science Department
26  *                         University of Maryland at College Park
27  */
28 /*
29  * $Id: sl.c,v 1.6 2006/05/25 01:47:12 johnfranks Exp $
30  *
31  * A doubly linked list of string (char *)
32  */
33
34 #include "amanda.h"
35 #include "am_sl.h"
36
37
38 void init_sl(
39     am_sl_t *sl)
40 {
41     sl->first = NULL;
42     sl->last  = NULL;
43     sl->nb_element = 0;
44 }
45
46
47 am_sl_t *
48 new_sl(void)
49 {
50     am_sl_t *sl;
51     sl = alloc(SIZEOF(am_sl_t));
52     init_sl(sl);
53     return(sl);
54 }
55
56
57 am_sl_t *
58 insert_sl(
59     am_sl_t *sl,
60     char *name)
61 {
62     sle_t *a;
63
64     if(!sl) {
65         sl = new_sl();
66     }
67     a = alloc(SIZEOF(sle_t));
68     a->name = stralloc(name);
69     a->next = sl->first;
70     a->prev = NULL;
71     if(a->next)
72         a->next->prev = a;
73     else
74         sl->last = a;
75     sl->first = a;
76     sl->nb_element++;
77     return(sl);
78 }
79
80
81 am_sl_t *
82 append_sl(
83     am_sl_t *   sl,
84     char *      name)
85 {
86     sle_t *a;
87
88     if(!sl) {
89         sl = new_sl();
90     }
91     a = alloc(SIZEOF(sle_t));
92     a->name = stralloc(name);
93     a->prev = sl->last;
94     a->next = NULL;
95     if(a->prev)
96         a->prev->next = a;
97     else
98         sl->first = a;
99     sl->last = a;
100     sl->nb_element++;
101     return(sl);
102 }
103
104
105 am_sl_t *
106 insert_sort_sl(
107     am_sl_t *   sl,
108     char *      name)
109 {
110     sle_t *a, *b;
111
112     if(!sl) {
113         sl = new_sl();
114     }
115
116     for(b=sl->first; b != NULL; b=b->next) {
117         int i = strcmp(b->name, name);
118         if(i==0) return(sl); /* already there, no need to insert */
119         if(i>0) break;
120     }
121
122     if(b == sl->first) return insert_sl(sl, name);
123     if(b == NULL)      return append_sl(sl, name);
124
125     a = alloc(SIZEOF(sle_t));
126     a->name = stralloc(name);
127
128     /* insert before b */
129     a->next = b;
130     a->prev = b->prev;
131     b->prev->next = a;
132     b->prev = a;
133     sl->nb_element++;
134     return(sl);
135 }
136
137
138 void
139 free_sl(
140     am_sl_t *   sl)
141 {
142     sle_t *a, *b;
143
144     if(!sl) return;
145
146     a = sl->first;
147     while(a != NULL) {
148         b = a;
149         a = a->next;
150         amfree(b->name);
151         amfree(b);
152     }
153     amfree(sl);
154 }
155
156
157 void
158 remove_sl(
159     am_sl_t *   sl,
160     sle_t *     elem)
161 {
162     if(elem->prev)
163         elem->prev->next = elem->next;
164     else
165         sl->first = elem->next;
166
167     if(elem->next)
168         elem->next->prev = elem->prev;
169     else
170         sl->last = elem->prev;
171
172     sl->nb_element--;
173
174     amfree(elem->name);
175     amfree(elem);
176 }
177
178
179 am_sl_t *
180 duplicate_sl(
181     am_sl_t *   sl)
182 {
183     am_sl_t *new_sl = NULL;
184     sle_t *a;
185
186     if(!sl) return new_sl;
187
188     for(a = sl->first; a != NULL; a = a->next) {
189         new_sl = append_sl(new_sl, a->name);
190     }
191
192     return new_sl;
193 }
194
195 /*
196  * Return "true" iff sl is empty (i.e. contains no elements).
197  */
198 int
199 is_empty_sl(
200     am_sl_t *   sl)
201 {
202     if (sl == NULL)
203         return 1;
204
205     return (sl->nb_element == 0);
206 }