Drop the 'Functions declared include:' comment sections
[privoxy.git] / list.c
1 const char list_rcs[] = "$Id: list.c,v 1.25 2011/09/04 11:10:56 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/list.c,v $
5  *
6  * Purpose     :  Declares functions to handle lists.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001-2007 the SourceForge
9  *                Privoxy team. http://www.privoxy.org/
10  *
11  *                Based on the Internet Junkbuster originally written
12  *                by and Copyright (C) 1997 Anonymous Coders and
13  *                Junkbusters Corporation.  http://www.junkbusters.com
14  *
15  *                This program is free software; you can redistribute it
16  *                and/or modify it under the terms of the GNU General
17  *                Public License as published by the Free Software
18  *                Foundation; either version 2 of the License, or (at
19  *                your option) any later version.
20  *
21  *                This program is distributed in the hope that it will
22  *                be useful, but WITHOUT ANY WARRANTY; without even the
23  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
24  *                PARTICULAR PURPOSE.  See the GNU General Public
25  *                License for more details.
26  *
27  *                The GNU General Public License should be included with
28  *                this file.  If not, you can view it at
29  *                http://www.gnu.org/copyleft/gpl.html
30  *                or write to the Free Software Foundation, Inc., 59
31  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  *
33  *********************************************************************/
34
35
36 #include "config.h"
37
38 #ifndef _WIN32
39 /* FIXME: The following headers are not needed for Win32.  Are they
40  * needed on other platforms?
41  */
42 #include <stdio.h>
43 #include <sys/types.h>
44 #include <stdlib.h>
45 #include <ctype.h>
46 #endif
47 #include <string.h>
48
49 #if !defined(_WIN32) && !defined(__OS2__)
50 #include <unistd.h>
51 #endif
52
53 #include <assert.h>
54
55 #include "project.h"
56 #include "list.h"
57 #include "miscutil.h"
58
59 const char list_h_rcs[] = LIST_H_VERSION;
60
61
62 static int list_is_valid (const struct list *the_list);
63
64
65 /*********************************************************************
66  *
67  * Function    :  init_list
68  *
69  * Description :  Create a new, empty list in user-allocated memory.
70  *                Caller should allocate a "struct list" variable,
71  *                then pass it to this function.
72  *                (Implementation note:  Rather than calling this
73  *                function, you can also just memset the memory to
74  *                zero, e.g. if you have a larger structure you
75  *                want to initialize quickly.  However, that isn't
76  *                really good design.)
77  *
78  * Parameters  :
79  *          1  :  the_list = pointer to list
80  *
81  * Returns     :  N/A
82  *
83  *********************************************************************/
84 void init_list(struct list *the_list)
85 {
86    memset(the_list, '\0', sizeof(*the_list));
87 }
88
89
90 /*********************************************************************
91  *
92  * Function    :  destroy_list
93  *
94  * Description :  Destroy a string list (opposite of list_init).
95  *                On return, the memory used by the list entries has
96  *                been freed, but not the memory used by the_list
97  *                itself.  You should not re-use the_list without
98  *                calling list_init().
99  *
100  *                (Implementation note:  You *can* reuse the_list
101  *                without calling list_init(), but please don't.
102  *                If you want to remove all entries from a list
103  *                and still have a usable list, then use
104  *                list_remove_all().)
105  *
106  * Parameters  :
107  *          1  :  the_list = pointer to list
108  *
109  * Returns     :  N/A
110  *
111  *********************************************************************/
112 void destroy_list (struct list *the_list)
113 {
114    struct list_entry *cur_entry, *next_entry;
115
116    assert(the_list);
117
118    for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
119    {
120       next_entry = cur_entry->next;
121       freez(cur_entry->str);
122       free(cur_entry);
123    }
124
125    the_list->first = NULL;
126    the_list->last = NULL;
127 }
128
129
130 /*********************************************************************
131  *
132  * Function    :  list_is_valid
133  *
134  * Description :  Check that a string list is valid.  The intended
135  *                usage is "assert(list_is_valid(the_list))".
136  *                Currently this checks that "the_list->last"
137  *                is correct, and that the list dosn't contain
138  *                circular references.  It is likely to crash if
139  *                it's passed complete garbage.
140  *
141  * Parameters  :
142  *          1  :  the_list = pointer to list.  Must be non-null.
143  *
144  * Returns     :  1 if list is valid, 0 otherwise.
145  *
146  *********************************************************************/
147 static int list_is_valid (const struct list *the_list)
148 {
149    /*
150     * If you don't want this check, just change the line below
151     * from "#if 1" to "#if 0".
152     */
153 #if 1
154    const struct list_entry *cur_entry;
155    const struct list_entry *last_entry = NULL;
156    int entry = 0;
157
158    assert(the_list);
159
160    for (cur_entry = the_list->first; cur_entry ; cur_entry = cur_entry->next)
161    {
162       last_entry = cur_entry;
163
164       if (cur_entry->str)
165       {
166          /*
167           * Just check that this string can be accessed - i.e. it's a valid
168           * pointer.
169           */
170          (void)strlen(cur_entry->str);
171       }
172
173       /*
174        * Check for looping back to first
175        */
176       if ((entry++ != 0) && (cur_entry == the_list->first))
177       {
178          return 0;
179       }
180
181       /*
182        * Arbitrarily limit list length to prevent infinite loops.
183        * Note that the 1000 limit was hit by a real user in tracker 911950;
184        * removing it for now.  Real circular references should eventually
185        * be caught by the check above, anyway.
186        */
187       /*
188       if (entry > 1000)
189       {
190          return 0;
191       }
192       */
193
194       /*
195        * Check this isn't marked as the last entry, unless of course it's
196        * *really* the last entry.
197        */
198       if ((the_list->last == cur_entry) && (cur_entry->next != NULL))
199       {
200          /* This is the last entry, but there's data after it !!?? */
201          return 0;
202       }
203    }
204
205    return (the_list->last == last_entry);
206 #else
207    return 1;
208 #endif
209 }
210
211 /*********************************************************************
212  *
213  * Function    :  enlist
214  *
215  * Description :  Append a string into a specified string list.
216  *
217  * Parameters  :
218  *          1  :  the_list = pointer to list
219  *          2  :  str = string to add to the list (maybe NULL)
220  *
221  * Returns     :  JB_ERR_OK on success
222  *                JB_ERR_MEMORY on out-of-memory error.
223  *                On error, the_list will be unchanged.
224  *
225  *********************************************************************/
226 jb_err enlist(struct list *the_list, const char *str)
227 {
228    struct list_entry *cur;
229
230    assert(the_list);
231    assert(list_is_valid(the_list));
232
233    if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
234    {
235       return JB_ERR_MEMORY;
236    }
237
238    if (str)
239    {
240       if (NULL == (cur->str = strdup(str)))
241       {
242          free(cur);
243          return JB_ERR_MEMORY;
244       }
245    }
246    /* else { cur->str = NULL; }  - implied by zalloc */
247
248    /* cur->next = NULL;  - implied by zalloc */
249
250    if (the_list->last)
251    {
252       the_list->last->next = cur;
253       the_list->last = cur;
254    }
255    else
256    {
257       the_list->first = cur;
258       the_list->last = cur;
259    }
260
261    assert(list_is_valid(the_list));
262    return JB_ERR_OK;
263 }
264
265
266 /*********************************************************************
267  *
268  * Function    :  enlist_first
269  *
270  * Description :  Append a string as first element into a specified
271  *                string list.
272  *
273  * Parameters  :
274  *          1  :  the_list = pointer to list
275  *          2  :  str = string to add to the list (maybe NULL)
276  *
277  * Returns     :  JB_ERR_OK on success
278  *                JB_ERR_MEMORY on out-of-memory error.
279  *                On error, the_list will be unchanged.
280  *
281  *********************************************************************/
282 jb_err enlist_first(struct list *the_list, const char *str)
283 {
284    struct list_entry *cur;
285
286    assert(the_list);
287    assert(list_is_valid(the_list));
288
289    if (NULL == (cur = (struct list_entry *)zalloc(sizeof(*cur))))
290    {
291       return JB_ERR_MEMORY;
292    }
293
294    if (str)
295    {
296       if (NULL == (cur->str = strdup(str)))
297       {
298          free(cur);
299          return JB_ERR_MEMORY;
300       }
301    }
302    /* else { cur->str = NULL; }  - implied by zalloc */
303
304    cur->next = the_list->first;
305
306    the_list->first = cur;
307    if (the_list->last == NULL)
308    {
309       the_list->last = cur;
310    }
311
312    assert(list_is_valid(the_list));
313    return JB_ERR_OK;
314 }
315
316
317 /*********************************************************************
318  *
319  * Function    :  enlist_unique
320  *
321  * Description :  Append a string into a specified string list,
322  *                if & only if it's not there already.
323  *                If the num_significant_chars argument is nonzero,
324  *                only compare up to the nth character.
325  *
326  * Parameters  :
327  *          1  :  the_list = pointer to list
328  *          2  :  str = string to add to the list
329  *          3  :  num_significant_chars = number of chars to use
330  *                for uniqueness test, or 0 to require an exact match.
331  *
332  * Returns     :  JB_ERR_OK on success
333  *                JB_ERR_MEMORY on out-of-memory error.
334  *                On error, the_list will be unchanged.
335  *                "Success" does not indicate whether or not the
336  *                item was already in the list.
337  *
338  *********************************************************************/
339 jb_err enlist_unique(struct list *the_list, const char *str,
340                      size_t num_significant_chars)
341 {
342    struct list_entry *cur_entry;
343
344    assert(the_list);
345    assert(list_is_valid(the_list));
346    assert(str);
347    assert(num_significant_chars >= 0);
348    assert(num_significant_chars <= strlen(str));
349
350    if (num_significant_chars > 0)
351    {
352       for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
353       {
354          if ( (cur_entry->str != NULL)
355            && (0 == strncmp(str, cur_entry->str, num_significant_chars)))
356          {
357             /* Already there */
358             return JB_ERR_OK;
359          }
360       }
361    }
362    else
363    {
364       /* Test whole string */
365       for (cur_entry = the_list->first; cur_entry != NULL; cur_entry = cur_entry->next)
366       {
367          if ( (cur_entry->str != NULL) && (0 == strcmp(str, cur_entry->str)))
368          {
369             /* Already there */
370             return JB_ERR_OK;
371          }
372       }
373    }
374
375    return enlist(the_list, str);
376 }
377
378
379 /*********************************************************************
380  *
381  * Function    :  enlist_unique_header
382  *
383  * Description :  Make a HTTP header from the two strings name and value,
384  *                and append the result into a specified string list,
385  *                if & only if there isn't already a header with that name.
386  *
387  * Parameters  :
388  *          1  :  the_list = pointer to list
389  *          2  :  name = HTTP header name (e.g. "Content-type")
390  *          3  :  value = HTTP header value (e.g. "text/html")
391  *
392  * Returns     :  JB_ERR_OK on success
393  *                JB_ERR_MEMORY on out-of-memory error.
394  *                On error, the_list will be unchanged.
395  *                "Success" does not indicate whether or not the
396  *                header was already in the list.
397  *
398  *********************************************************************/
399 jb_err enlist_unique_header(struct list *the_list, const char *name,
400                             const char *value)
401 {
402    jb_err result = JB_ERR_MEMORY;
403    char *header;
404    size_t header_size;
405
406    assert(the_list);
407    assert(list_is_valid(the_list));
408    assert(name);
409    assert(value);
410
411    /* + 2 for the ': ', + 1 for the \0 */
412    header_size = strlen(name) + 2 + strlen(value) + 1;
413    header = (char *)malloc(header_size);
414
415    if (NULL != header)
416    {
417       const size_t bytes_to_compare = strlen(name) + 2;
418
419       snprintf(header, header_size, "%s: %s", name, value);
420       result = enlist_unique(the_list, header, bytes_to_compare);
421       free(header);
422       assert(list_is_valid(the_list));
423    }
424
425    return result;
426
427 }
428
429
430 /*********************************************************************
431  *
432  * Function    :  list_remove_all
433  *
434  * Description :  Remove all entries from a list.  On return, the_list
435  *                is a valid, empty list.  Note that this is similar
436  *                to destroy_list(), but the difference is that this
437  *                function guarantees that the list structure is still
438  *                valid after the call.
439  *
440  * Parameters  :
441  *          1  :  the_list = pointer to list
442  *
443  * Returns     :  N/A
444  *
445  *********************************************************************/
446 void list_remove_all(struct list *the_list)
447 {
448    struct list_entry *cur_entry;
449    struct list_entry *next_entry;
450
451    assert(the_list);
452    assert(list_is_valid(the_list));
453
454    for (cur_entry = the_list->first; cur_entry ; cur_entry = next_entry)
455    {
456       next_entry = cur_entry->next;
457       freez(cur_entry->str);
458       free(cur_entry);
459    }
460
461    the_list->first = the_list->last = NULL;
462
463    assert(list_is_valid(the_list));
464 }
465
466
467 /*********************************************************************
468  *
469  * Function    :  list_to_text
470  *
471  * Description :  "Flatten" a string list into 1 long \r\n delimited string,
472  *                adding an empty line at the end.  NULL entries are ignored.
473  *                This function does not change the_list.
474  *
475  *                XXX: Should probably be renamed as it's only
476  *                useful (and used) to flatten header lists.
477  *
478  * Parameters  :
479  *          1  :  the_list = pointer to list
480  *
481  * Returns     :  NULL on malloc error, else new long string.
482  *                Caller must free() it.
483  *
484  *********************************************************************/
485 char *list_to_text(const struct list *the_list)
486 {
487    struct list_entry *cur_entry;
488    char *text;
489    size_t text_length;
490    char *cursor;
491    size_t bytes_left;
492
493    assert(the_list);
494    assert(list_is_valid(the_list));
495
496    /*
497     * Calculate the length of the final text.
498     * '2' because of the '\r\n' at the end of
499     * each string and at the end of the text.
500     */
501    text_length = 2;
502    for (cur_entry = the_list->first; cur_entry; cur_entry = cur_entry->next)
503    {
504       if (cur_entry->str)
505       {
506          text_length += strlen(cur_entry->str) + 2;
507       }
508    }
509
510    bytes_left = text_length + 1;
511
512    text = (char *)malloc(bytes_left);
513    if (NULL == text)
514    {
515       return NULL;
516    }
517
518    cursor = text;
519
520    for (cur_entry = the_list->first; cur_entry; cur_entry = cur_entry->next)
521    {
522       if (cur_entry->str)
523       {
524          const int written = snprintf(cursor, bytes_left, "%s\r\n", cur_entry->str);
525
526          assert(written > 0);
527          assert(written < bytes_left);
528
529          bytes_left -= (size_t)written;
530          cursor += (size_t)written;
531       }
532    }
533
534    assert(bytes_left == 3);
535
536    *cursor++ = '\r';
537    *cursor++ = '\n';
538    *cursor   = '\0';
539
540    assert(text_length == cursor - text);
541    assert(text[text_length] == '\0');
542
543    return text;
544 }
545
546
547 /*********************************************************************
548  *
549  * Function    :  list_remove_item
550  *
551  * Description :  Remove a string from a specified string list.
552  *
553  * Parameters  :
554  *          1  :  the_list = pointer to list
555  *          2  :  str = string to remove from the list - non-NULL
556  *
557  * Returns     :  Number of times it was removed.
558  *
559  *********************************************************************/
560 int list_remove_item(struct list *the_list, const char *str)
561 {
562    struct list_entry *prev = NULL;
563    struct list_entry *cur;
564    struct list_entry *next;
565    int count = 0;
566
567    assert(the_list);
568    assert(list_is_valid(the_list));
569    assert(str);
570
571    cur = the_list->first;
572
573    while (cur != NULL)
574    {
575       next = cur->next;
576
577       if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
578       {
579          count++;
580
581          if (prev != NULL)
582          {
583             prev->next = next;
584          }
585          else
586          {
587             the_list->first = next;
588          }
589          free((char *)cur->str);
590          free(cur);
591       }
592       else
593       {
594          prev = cur;
595       }
596       cur = next;
597    }
598
599    the_list->last = prev;
600
601    assert(list_is_valid(the_list));
602
603    return count;
604 }
605
606
607 /*********************************************************************
608  *
609  * Function    :  list_remove_list
610  *
611  * Description :  Remove all strings in one list from another list.
612  *                This is currently a brute-force algorithm
613  *                (it compares every pair of strings).
614  *
615  * Parameters  :
616  *          1  :  dest = list to change
617  *          2  :  src = list of strings to remove
618  *
619  * Returns     :  Total number of strings removed.
620  *
621  *********************************************************************/
622 int list_remove_list(struct list *dest, const struct list *src)
623 {
624    struct list_entry *cur;
625    int count = 0;
626
627    assert(src);
628    assert(dest);
629    assert(list_is_valid(src));
630    assert(list_is_valid(dest));
631
632    for (cur = src->first; cur != NULL; cur = cur->next)
633    {
634       if (cur->str != NULL)
635       {
636          count += list_remove_item(dest, cur->str);
637       }
638    }
639
640    assert(list_is_valid(src));
641    assert(list_is_valid(dest));
642
643    return count;
644 }
645
646
647 /*********************************************************************
648  *
649  * Function    :  list_duplicate
650  *
651  * Description :  Copy a string list
652  *
653  * Parameters  :
654  *          1  :  dest = Destination list.  Must be a valid list.
655  *                       All existing entries will be removed.
656  *          1  :  src = pointer to source list for copy.
657  *
658  * Returns     :  JB_ERR_OK on success
659  *                JB_ERR_MEMORY on out-of-memory error.
660  *                On error, dest will be empty.
661  *
662  *********************************************************************/
663 jb_err list_duplicate(struct list *dest, const struct list *src)
664 {
665    struct list_entry * cur_src;
666    struct list_entry * cur_dest;
667
668    assert(src);
669    assert(dest);
670    assert(list_is_valid(src));
671    assert(list_is_valid(dest));
672
673    list_remove_all(dest);
674
675    /* Need to process first entry specially so we can set dest->first */
676    cur_src = src->first;
677    if (cur_src)
678    {
679       cur_dest = dest->first = (struct list_entry *)zalloc(sizeof(*cur_dest));
680       if (cur_dest == NULL)
681       {
682          destroy_list(dest);
683
684          assert(list_is_valid(src));
685          assert(list_is_valid(dest));
686
687          return JB_ERR_MEMORY;
688       }
689
690       if (cur_src->str)
691       {
692          cur_dest->str = strdup(cur_src->str);
693          if (cur_dest->str == NULL)
694          {
695             destroy_list(dest);
696
697             assert(list_is_valid(src));
698             assert(list_is_valid(dest));
699
700             return JB_ERR_MEMORY;
701          }
702       }
703       /* else { cur_dest->str = NULL; }  - implied by zalloc */
704
705       /* Now process the rest */
706       for (cur_src = cur_src->next; cur_src; cur_src = cur_src->next)
707       {
708          cur_dest = cur_dest->next = (struct list_entry *)zalloc(sizeof(*cur_dest));
709          if (cur_dest == NULL)
710          {
711             destroy_list(dest);
712
713             assert(list_is_valid(src));
714             assert(list_is_valid(dest));
715
716             return JB_ERR_MEMORY;
717          }
718          if (cur_src->str)
719          {
720             cur_dest->str = strdup(cur_src->str);
721             if (cur_dest->str == NULL)
722             {
723                destroy_list(dest);
724
725                assert(list_is_valid(src));
726                assert(list_is_valid(dest));
727
728                return JB_ERR_MEMORY;
729             }
730          }
731          /* else { cur_dest->str = NULL; }  - implied by zalloc */
732       }
733
734       dest->last = cur_dest;
735    }
736
737    assert(list_is_valid(src));
738    assert(list_is_valid(dest));
739
740    return JB_ERR_OK;
741 }
742
743
744 /*********************************************************************
745  *
746  * Function    :  list_append_list_unique
747  *
748  * Description :  Append a string list to another list.
749  *                Duplicate items are not added.
750  *
751  * Parameters  :
752  *          1  :  dest = pointer to destination list for merge.
753  *          2  :  src = pointer to source for merge.
754  *
755  * Returns     :  JB_ERR_OK on success
756  *                JB_ERR_MEMORY on out-of-memory error.
757  *                On error, some (but not all) of src might have
758  *                been copied into dest.
759  *
760  *********************************************************************/
761 jb_err list_append_list_unique(struct list *dest, const struct list *src)
762 {
763    struct list_entry * cur;
764
765    assert(src);
766    assert(dest);
767    assert(list_is_valid(src));
768    assert(list_is_valid(dest));
769
770    for (cur = src->first; cur; cur = cur->next)
771    {
772       if (cur->str)
773       {
774          if (enlist_unique(dest, cur->str, 0))
775          {
776             assert(list_is_valid(src));
777             assert(list_is_valid(dest));
778
779             return JB_ERR_MEMORY;
780          }
781       }
782    }
783
784    assert(list_is_valid(src));
785    assert(list_is_valid(dest));
786
787    return JB_ERR_OK;
788 }
789
790
791 /*********************************************************************
792  *
793  * Function    :  list_is_empty
794  *
795  * Description :  Test whether a list is empty.  Does not change the list.
796  *
797  * Parameters  :
798  *          1  :  the_list = pointer to list to test.
799  *
800  * Returns     :  Nonzero if the list contains no entries.
801  *
802  *********************************************************************/
803 int list_is_empty(const struct list *the_list)
804 {
805    assert(the_list);
806    assert(list_is_valid(the_list));
807
808    return (the_list->first == NULL);
809 }
810
811
812 /*********************************************************************
813  *
814  * Function    :  list_contains_item
815  *
816  * Description :  Tests whether a list item is already set.
817  *                Does not change the list.
818  *
819  * Parameters  :
820  *          1  :  the_list = list to search in
821  *          2  :  str = string to search for
822  *
823  * Returns     :  TRUE if the item was found,
824  *                FALSE otherwise.
825  *
826  *********************************************************************/
827 int list_contains_item(const struct list *the_list, const char *str)
828 {
829    struct list_entry *entry;
830
831    assert(the_list);
832    assert(list_is_valid(the_list));
833    assert(str);
834
835    for (entry = the_list->first; entry != NULL; entry = entry->next)
836    {
837       if (entry->str == NULL)
838       {
839          /*
840           * NULL pointers are allowed in some lists.
841           * For example for csp->headers in case a
842           * header was removed.
843           */
844          continue;
845       }
846
847       if (0 == strcmp(str, entry->str))
848       {
849          /* Item found */
850          return TRUE;
851       }
852    }
853
854    return FALSE;
855 }
856
857
858 /*********************************************************************
859  *
860  * Function    :  new_map
861  *
862  * Description :  Create a new, empty map.
863  *
864  * Parameters  :  N/A
865  *
866  * Returns     :  A new, empty map, or NULL if out of memory.
867  *
868  *********************************************************************/
869 struct map *new_map(void)
870 {
871    return (struct map *) zalloc(sizeof(struct map));
872 }
873
874
875 /*********************************************************************
876  *
877  * Function    :  free_map
878  *
879  * Description :  Free the memory occupied by a map and its
880  *                depandant strings
881  *
882  * Parameters  :
883  *          1  :  the_map = map to be freed.  May be NULL.
884  *
885  * Returns     :  N/A
886  *
887  *********************************************************************/
888 void free_map(struct map *the_map)
889 {
890    struct map_entry *cur_entry;
891    struct map_entry *next_entry;
892
893    if (the_map == NULL)
894    {
895       return;
896    }
897
898    for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry)
899    {
900       freez(cur_entry->name);
901       freez(cur_entry->value);
902
903       next_entry = cur_entry->next;
904       free(cur_entry);
905    }
906
907    the_map->first = the_map->last = NULL;
908
909    free(the_map);
910 }
911
912
913 /*********************************************************************
914  *
915  * Function    :  map
916  *
917  * Description :  Add a mapping from given name to given value to a
918  *                given map.
919  *
920  *                Note: Since all strings will be free()d in free_map()
921  *                      later, set the copy flags for constants or
922  *                      strings that will be independently free()d.
923  *
924  *                Note2: This function allows NULL parameters - it
925  *                       returns JB_ERR_MEMORY in that case.
926  *
927  *                Note3: If this function returns JB_ERR_MEMORY,
928  *                       it will free(name) unless you specify
929  *                       name_needs_copying, and similarly it will
930  *                       free(value) unless you specify
931  *                       value_needs_copying.
932  *
933  *                Due to Note2 and Note3 above, the following code
934  *                is legal, and will never crash or leak memory even
935  *                if the system runs out of memory:
936  *
937  *                    err = map(mymap, "xyz", 1, html_encode(somestring), 0);
938  *
939  *                err will be set to JB_ERR_MEMORY if either call runs
940  *                out-of-memory.  Without these features, you would
941  *                need to check the return value of html_encode in the
942  *                above example for NULL, which (at least) doubles the
943  *                amount of error-checking code needed.
944  *
945  * Parameters  :
946  *          1  :  the_map = map to add to
947  *          2  :  name = name to add
948  *          3  :  name_needs_copying = flag set if a copy of name should be used
949  *          4  :  value = value to add
950  *          5  :  value_needs_copying = flag set if a copy of value should be used
951  *
952  * Returns     :  JB_ERR_OK on success
953  *                JB_ERR_MEMORY on out-of-memory error.
954  *
955  *********************************************************************/
956 jb_err map(struct map *the_map,
957            const char *name, int name_needs_copying,
958            const char *value, int value_needs_copying)
959 {
960    struct map_entry *new_entry;
961
962    assert(the_map);
963
964    if ( (NULL == value)
965      || (NULL == name)
966      || (NULL == (new_entry = zalloc(sizeof(*new_entry)))) )
967    {
968       if ((name != NULL) && (!name_needs_copying))
969       {
970           free((char *)name);
971       }
972       if ((value != NULL) && (!value_needs_copying))
973       {
974           free((char *)value);
975       }
976       return JB_ERR_MEMORY;
977    }
978
979    if (name_needs_copying)
980    {
981       if (NULL == (name = strdup(name)))
982       {
983          free(new_entry);
984          if (!value_needs_copying)
985          {
986              free((char *)value);
987          }
988          return JB_ERR_MEMORY;
989       }
990    }
991
992    if (value_needs_copying)
993    {
994       if (NULL == (value = strdup(value)))
995       {
996          free((char *)name);
997          free(new_entry);
998          return JB_ERR_MEMORY;
999       }
1000    }
1001
1002    new_entry->name = name;
1003    new_entry->value = value;
1004    /* new_entry->next = NULL;  - implied by zalloc */
1005
1006    if (the_map->last)
1007    {
1008       the_map->last->next = new_entry;
1009       the_map->last = new_entry;
1010    }
1011    else
1012    {
1013       the_map->first = new_entry;
1014       the_map->last = new_entry;
1015    }
1016
1017    return JB_ERR_OK;
1018 }
1019
1020
1021 /*********************************************************************
1022  *
1023  * Function    :  unmap
1024  *
1025  * Description :  Remove all map_entry structs with a given name from
1026  *                a given map.
1027  *
1028  * Parameters  :
1029  *          1  :  the_map = map to look in
1030  *          2  :  name = name to unmap
1031  *
1032  * Returns     :  JB_ERR_OK
1033  *
1034  *********************************************************************/
1035 jb_err unmap(struct map *the_map, const char *name)
1036 {
1037    struct map_entry *cur_entry, *last_entry;
1038
1039    assert(the_map);
1040    assert(name);
1041
1042    last_entry = the_map->first;
1043
1044    for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next)
1045    {
1046       if (!strcmp(name, cur_entry->name))
1047       {
1048          /*
1049           * Update the incoming pointer
1050           */
1051          if (cur_entry == the_map->first)
1052          {
1053             the_map->first = cur_entry->next;
1054          }
1055          else
1056          {
1057             last_entry->next = cur_entry->next;
1058          }
1059
1060          /*
1061           * Update the map's last pointer
1062           */
1063          if (cur_entry == the_map->last)
1064          {
1065             the_map->last = last_entry;
1066          }
1067
1068          /*
1069           * Free the map_entry
1070           */
1071          freez(cur_entry->name);
1072          freez(cur_entry->value);
1073          freez(cur_entry);
1074
1075          cur_entry = last_entry;
1076       }
1077       else
1078       {
1079          last_entry = cur_entry;
1080       }
1081    }
1082    return JB_ERR_OK;
1083 }
1084
1085
1086 /*********************************************************************
1087  *
1088  * Function    :  lookup
1089  *
1090  * Description :  Look up an item with a given name in a map, and
1091  *                return its value
1092  *
1093  * Parameters  :
1094  *          1  :  the_map = map to look in
1095  *          2  :  name = name parameter to look for
1096  *
1097  * Returns     :  the value if found, else the empty string.
1098  *                Return value is alloced as part of the map, so
1099  *                it is freed when the map is destroyed.  Caller
1100  *                must not free or modify it.
1101  *
1102  *********************************************************************/
1103 const char *lookup(const struct map *the_map, const char *name)
1104 {
1105    const struct map_entry *cur_entry;
1106
1107    assert(the_map);
1108    assert(name);
1109
1110    for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = cur_entry->next)
1111    {
1112       if (!strcmp(name, cur_entry->name))
1113       {
1114          return cur_entry->value;
1115       }
1116    }
1117    return "";
1118 }
1119
1120
1121 /*
1122   Local Variables:
1123   tab-width: 3
1124   end:
1125 */