introduced confdir option
[privoxy.git] / list.c
1 const char list_rcs[] = "$Id: list.c,v 1.1 2001/05/31 21:11:53 jongfoster Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/list.c,v $
5  *
6  * Purpose     :  Declares functions to handle lists.
7  *                Functions declared include:
8  *                   `destroy_list', `enlist' and `list_to_text'
9  *
10  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
11  *                IJBSWA team.  http://ijbswa.sourceforge.net
12  *
13  *                Based on the Internet Junkbuster originally written
14  *                by and Copyright (C) 1997 Anonymous Coders and 
15  *                Junkbusters Corporation.  http://www.junkbusters.com
16  *
17  *                This program is free software; you can redistribute it 
18  *                and/or modify it under the terms of the GNU General
19  *                Public License as published by the Free Software
20  *                Foundation; either version 2 of the License, or (at
21  *                your option) any later version.
22  *
23  *                This program is distributed in the hope that it will
24  *                be useful, but WITHOUT ANY WARRANTY; without even the
25  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
26  *                PARTICULAR PURPOSE.  See the GNU General Public
27  *                License for more details.
28  *
29  *                The GNU General Public License should be included with
30  *                this file.  If not, you can view it at
31  *                http://www.gnu.org/copyleft/gpl.html
32  *                or write to the Free Software Foundation, Inc., 59
33  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34  *
35  * Revisions   :
36  *    $Log: list.c,v $
37  *    Revision 1.1  2001/05/31 21:11:53  jongfoster
38  *    - Moved linked list support to new "list.c" file.
39  *      Structure definitions are still in project.h,
40  *      function prototypes are now in "list.h".
41  *    - Added support for "struct list_share", which is identical
42  *      to "struct list" except it saves memory by not duplicating
43  *      the strings.  Obviously, this only works if there is some
44  *      other way of managing the memory used by the strings.
45  *      (These list_share lists are used for lists which last
46  *      for only 1 request, and where all the list entries are
47  *      just coming directly from entries in the actionsfile.)
48  *      Note that you still need to destroy list_share lists
49  *      properly to free the nodes - it's only the strings
50  *      which are shared.
51  *
52  *
53  *********************************************************************/
54 \f
55
56 #include "config.h"
57
58 #include <stdio.h>
59 #include <sys/types.h>
60 #include <stdlib.h>
61 #include <ctype.h>
62 #include <string.h>
63
64 #ifndef _WIN32
65 #include <unistd.h>
66 #endif
67
68 #include "project.h"
69 #include "jcc.h"
70 #include "list.h"
71 #include "miscutil.h"
72
73 const char list_h_rcs[] = LIST_H_VERSION;
74
75 /*********************************************************************
76  *
77  * Function    :  enlist
78  *
79  * Description :  Append a string into a specified string list.
80  *
81  * Parameters  :
82  *          1  :  header = pointer to list 'dummy' header
83  *          2  :  str = string to add to the list (maybe NULL)
84  *
85  * Returns     :  N/A
86  *
87  *********************************************************************/
88 void enlist(struct list *header, const char *str)
89 {
90    struct list *cur = (struct list *)malloc(sizeof(*cur));
91    struct list *last;
92
93    if (cur)
94    {
95       cur->str  = (str ? strdup(str) : NULL);
96       cur->next = NULL;
97
98       last = header->last;
99       if (last == NULL)
100       {
101          last = header;
102       }
103
104       last->next   = cur;
105       header->last = cur;
106    }
107
108 }
109
110
111 /*********************************************************************
112  *
113  * Function    :  enlist_unique
114  *
115  * Description :  Append a string into a specified string list,
116  *                if & only if it's not there already.
117  *
118  * Parameters  :
119  *          1  :  header = pointer to list 'dummy' header
120  *          2  :  str = string to add to the list (maybe NULL)
121  *
122  * Returns     :  N/A
123  *
124  *********************************************************************/
125 void enlist_unique(struct list *header, const char *str)
126 {
127    struct list *last;
128    struct list *cur = header->next;
129
130    while (cur != NULL)
131    {
132       if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
133       {
134          /* Already there */
135          return;
136       }
137       cur = cur->next;
138    }
139
140    cur = (struct list *)malloc(sizeof(*cur));
141
142    if (cur != NULL)
143    {
144       cur->str  = (str ? strdup(str) : NULL); /* FIXME check retval */
145       cur->next = NULL;
146
147       last = header->last;
148       if (last == NULL)
149       {
150          last = header;
151       }
152       last->next   = cur;
153       header->last = cur;
154    }
155 }
156
157
158 /*********************************************************************
159  *
160  * Function    :  destroy_list
161  *
162  * Description :  Destroy a string list (opposite of enlist)
163  *
164  * Parameters  :
165  *          1  :  header = pointer to list 'dummy' header
166  *
167  * Returns     :  N/A
168  *
169  *********************************************************************/
170 void destroy_list(struct list *header)
171 {
172    struct list *p, *n;
173
174    for (p = header->next; p ; p = n)
175    {
176       n = p->next;
177       freez(p->str);
178       free(p);
179    }
180
181    memset(header, '\0', sizeof(*header));
182
183 }
184
185
186 /*********************************************************************
187  *
188  * Function    :  list_to_text
189  *
190  * Description :  "Flaten" a string list into 1 long \r\n delimited string.
191  *
192  * Parameters  :
193  *          1  :  h = pointer to list 'dummy' header
194  *
195  * Returns     :  NULL on malloc error, else new long string.
196  *
197  *********************************************************************/
198 char *list_to_text(struct list *h)
199 {
200    struct list *p;
201    char *ret = NULL;
202    char *s;
203    int size;
204
205    size = 0;
206
207    for (p = h->next; p ; p = p->next)
208    {
209       if (p->str)
210       {
211          size += strlen(p->str) + 2;
212       }
213    }
214
215    if ((ret = (char *)malloc(size + 1)) == NULL)
216    {
217       return(NULL);
218    }
219
220    ret[size] = '\0';
221
222    s = ret;
223
224    for (p = h->next; p ; p = p->next)
225    {
226       if (p->str)
227       {
228          strcpy(s, p->str);
229          s += strlen(s);
230          *s++ = '\r'; *s++ = '\n';
231       }
232    }
233
234    return(ret);
235
236 }
237
238
239 /*********************************************************************
240  *
241  * Function    :  list_remove_item
242  *
243  * Description :  Remove a string from a specified string list.
244  *
245  * Parameters  :
246  *          1  :  header = pointer to list 'dummy' header
247  *          2  :  str = string to remove from the list
248  *
249  * Returns     :  Number of times it was removed.
250  *
251  *********************************************************************/
252 int list_remove_item(struct list *header, const char *str)
253 {
254    struct list *prev = header;
255    struct list *cur = prev->next;
256    int count = 0;
257
258    while (cur != NULL)
259    {
260       if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
261       {
262          count++;
263
264          prev->next = cur->next;
265          free(cur->str);
266          free(cur);
267       }
268       else
269       {
270          prev = cur;
271       }
272       cur = prev->next;
273    }
274
275    header->last = prev;
276
277    return count;
278 }
279
280
281 /*********************************************************************
282  *
283  * Function    :  list_remove_list
284  *
285  * Description :  Remove all strings in one list from another list.
286  *                This is currently a brute-force algorithm
287  *                (it compares every pair of strings).
288  *
289  * Parameters  :
290  *          1  :  dest = list to change
291  *          2  :  src = list of strings to remove
292  *
293  * Returns     :  Total number of strings removed.
294  *
295  *********************************************************************/
296 int list_remove_list(struct list *dest, const struct list *src)
297 {
298    struct list *cur = src->next;
299    int count = 0;
300
301    while (cur != NULL)
302    {
303       if (cur->str != NULL)
304       {
305          count += list_remove_item(dest, cur->str);
306       }
307       cur = cur->next;
308    }
309
310    return count;
311 }
312
313
314 /*********************************************************************
315  *
316  * Function    :  list_duplicate
317  *
318  * Description :  Duplicate a string list
319  *
320  * Parameters  :
321  *          1  :  dest = pointer to destination for copy.  Caller allocs.
322  *          2  :  src = pointer to source for copy.
323  *
324  * Returns     :  N/A
325  *
326  *********************************************************************/
327 void list_duplicate(struct list *dest, const struct list *src)
328 {
329    struct list * cur_src = src->next;
330    struct list * cur_dest = dest;
331
332    memset(dest, '\0', sizeof(*dest));
333
334    while (cur_src)
335    {
336       cur_dest = cur_dest->next = (struct list *)zalloc(sizeof(*cur_dest));
337       if (cur_dest == NULL)
338       {
339          return;
340       }
341       cur_dest->str = strdup(cur_src->str);
342       cur_src = cur_src->next;
343    }
344
345    dest->last = cur_dest;
346
347 }
348
349
350 /*********************************************************************
351  *
352  * Function    :  list_append_list_unique
353  *
354  * Description :  Append a string list to another list.
355  *                Duplicate items are not added.
356  *
357  * Parameters  :
358  *          1  :  dest = pointer to destination for merge.  Caller allocs.
359  *          2  :  src = pointer to source for merge.
360  *
361  * Returns     :  N/A
362  *
363  *********************************************************************/
364 void list_append_list_unique(struct list *dest, const struct list *src)
365 {
366    struct list * cur = src->next;
367
368    while (cur)
369    {
370       enlist_unique(dest, cur->str);
371       cur = cur->next;
372    }
373 }
374
375 /*
376   Local Variables:
377   tab-width: 3
378   end:
379 */