X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=list.c;h=28552d80afe7bac4030277dffa22686909140b43;hb=ae6704a51522180202416c36a30a4d6d2914a0f5;hp=a44c0e9dd3837fb76cf877d129dbbd2fceb76ce3;hpb=31a3c127af9bc2bdea9d0b00526bdb5d03553fb7;p=privoxy.git diff --git a/list.c b/list.c index a44c0e9d..28552d80 100644 --- a/list.c +++ b/list.c @@ -1,4 +1,4 @@ -const char list_rcs[] = "$Id: list.c,v NOT CHECKED IN $"; +const char list_rcs[] = "$Id: list.c,v 1.7 2001/08/05 16:06:20 jongfoster Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/list.c,v $ @@ -34,6 +34,49 @@ const char list_rcs[] = "$Id: list.c,v NOT CHECKED IN $"; * * Revisions : * $Log: list.c,v $ + * Revision 1.7 2001/08/05 16:06:20 jongfoster + * Modifiying "struct map" so that there are now separate header and + * "map_entry" structures. This means that functions which modify a + * map no longer need to return a pointer to the modified map. + * Also, it no longer reverses the order of the entries (which may be + * important with some advanced template substitutions). + * + * Revision 1.6 2001/07/31 14:44:51 oes + * list_to_text() now appends empty line at end + * + * Revision 1.5 2001/06/29 21:45:41 oes + * Indentation, CRLF->LF, Tab-> Space + * + * Revision 1.4 2001/06/29 13:30:22 oes + * - Added Convenience function enlist_unique_header(), + * which takes the Header name and value as separate + * arguments and thus saves the pain of sprintf()ing + * and determining the Header name length to enlist_unique + * - Improved comments + * - Removed logentry from cancelled commit + * + * Revision 1.3 2001/06/03 19:12:24 oes + * functions for new struct map, extended enlist_unique + * + * Revision 1.2 2001/06/01 18:49:17 jongfoster + * Replaced "list_share" with "list" - the tiny memory gain was not + * worth the extra complexity. + * + * Revision 1.1 2001/05/31 21:11:53 jongfoster + * - Moved linked list support to new "list.c" file. + * Structure definitions are still in project.h, + * function prototypes are now in "list.h". + * - Added support for "struct list_share", which is identical + * to "struct list" except it saves memory by not duplicating + * the strings. Obviously, this only works if there is some + * other way of managing the memory used by the strings. + * (These list_share lists are used for lists which last + * for only 1 request, and where all the list entries are + * just coming directly from entries in the actionsfile.) + * Note that you still need to destroy list_share lists + * properly to free the nodes - it's only the strings + * which are shared. + * * *********************************************************************/ @@ -46,6 +89,8 @@ const char list_rcs[] = "$Id: list.c,v NOT CHECKED IN $"; #include #include +#include + #ifndef _WIN32 #include #endif @@ -57,6 +102,7 @@ const char list_rcs[] = "$Id: list.c,v NOT CHECKED IN $"; const char list_h_rcs[] = LIST_H_VERSION; + /********************************************************************* * * Function : enlist @@ -93,28 +139,66 @@ void enlist(struct list *header, const char *str) } +/********************************************************************* + * + * Function : enlist_first + * + * Description : Append a string as first element into a specified + * string list. + * + * Parameters : + * 1 : header = pointer to list 'dummy' header + * 2 : str = string to add to the list (maybe NULL) + * + * Returns : N/A + * + *********************************************************************/ +void enlist_first(struct list *header, const char *str) +{ + struct list *cur = (struct list *)malloc(sizeof(*cur)); + + if (cur) + { + cur->str = (str ? strdup(str) : NULL); + cur->next = header->next; + + header->next = cur; + if (header->last == NULL) + { + header->last = cur; + } + } + +} + + /********************************************************************* * * Function : enlist_unique * * Description : Append a string into a specified string list, * if & only if it's not there already. + * If the n argument is nonzero, only compare up to + * the nth character. * * Parameters : * 1 : header = pointer to list 'dummy' header * 2 : str = string to add to the list (maybe NULL) + * 3 : n = number of chars to use for uniqueness test * * Returns : N/A * *********************************************************************/ -void enlist_unique(struct list *header, const char *str) +void enlist_unique(struct list *header, const char *str, int n) { struct list *last; struct list *cur = header->next; while (cur != NULL) { - if ((cur->str != NULL) && (0 == strcmp(str, cur->str))) + if ((cur->str != NULL) && ( + (n && (0 == strncmp(str, cur->str, n))) || + (!n && (0 == strcmp(str, cur->str))))) { /* Already there */ return; @@ -140,6 +224,64 @@ void enlist_unique(struct list *header, const char *str) } +/********************************************************************* + * + * Function : enlist_unique_header + * + * Description : Make a HTTP header from the two strings name and value, + * and append the result into a specified string list, + * if & only if there isn't already a header with that name. + * + * Parameters : + * 1 : header = pointer to list 'dummy' header + * 2 : name = name of header to be added + * 3 : value = value of header to be added + * + * Returns : N/A + * + *********************************************************************/ +void enlist_unique_header(struct list *header, const char *name, const char *value) +{ + struct list *last; + struct list *cur = header->next; + int length; + char *dummy; + + if (name == NULL || value == NULL) return; + + dummy = strdup(name); + dummy = strsav(dummy, ": "); + length = strlen(dummy); + + while (cur != NULL) + { + if ((cur->str != NULL) && + (0 == strncmp(dummy, cur->str, length))) + { + /* Already there */ + return; + } + cur = cur->next; + } + + cur = (struct list *)malloc(sizeof(*cur)); + + if (cur != NULL) + { + cur->str = strsav(dummy, value); + cur->next = NULL; + + last = header->last; + if (last == NULL) + { + last = header; + } + last->next = cur; + header->last = cur; + } +} + + /********************************************************************* * * Function : destroy_list @@ -172,7 +314,8 @@ void destroy_list(struct list *header) * * Function : list_to_text * - * Description : "Flaten" a string list into 1 long \r\n delimited string. + * Description : "Flaten" a string list into 1 long \r\n delimited string, + * adding an empty line at the end. * * Parameters : * 1 : h = pointer to list 'dummy' header @@ -185,9 +328,7 @@ char *list_to_text(struct list *h) struct list *p; char *ret = NULL; char *s; - int size; - - size = 0; + int size = 2; for (p = h->next; p ; p = p->next) { @@ -215,6 +356,7 @@ char *list_to_text(struct list *h) *s++ = '\r'; *s++ = '\n'; } } + *s++ = '\r'; *s++ = '\n'; return(ret); @@ -336,7 +478,8 @@ void list_duplicate(struct list *dest, const struct list *src) * * Function : list_append_list_unique * - * Description : Append a string list to another list + * Description : Append a string list to another list. + * Duplicate items are not added. * * Parameters : * 1 : dest = pointer to destination for merge. Caller allocs. @@ -351,7 +494,7 @@ void list_append_list_unique(struct list *dest, const struct list *src) while (cur) { - enlist_unique(dest, cur->str); + enlist_unique(dest, cur->str, 0); cur = cur->next; } } @@ -359,245 +502,136 @@ void list_append_list_unique(struct list *dest, const struct list *src) /********************************************************************* * - * Function : destroy_list_share - * - * Description : Destroy a string list (opposite of enlist) - * - * Parameters : - * 1 : h = pointer to list 'dummy' header - * - * Returns : N/A - * - *********************************************************************/ -void destroy_list_share(struct list_share *h) -{ - struct list_share *p, *n; - - for (p = h->next; p ; p = n) - { - n = p->next; - free(p); - } - - memset(h, '\0', sizeof(*h)); - -} - - -/********************************************************************* + * Function : map * - * Function : enlist_share + * Description : Add a mapping from given name to given value to a + * given map. * - * Description : Append a string into a specified string list. + * Note: Since all strings will be free()d in free_map() + * later, use the copy flags for constants or + * strings that will be independantly free()d. * * Parameters : - * 1 : header = pointer to list 'dummy' header - * 2 : str = string to add to the list (maybe NULL) + * 1 : the_map = map to add to + * 2 : name = name to add + * 3 : nc = flag set if a copy of name should be used + * 4 : value = value to add + * 5 : vc = flag set if a copy of value should be used * * Returns : N/A * *********************************************************************/ -void enlist_share(struct list_share *header, const char *str) +void map(struct map *the_map, const char *name, int nc, const char *value, int vc) { - struct list_share *cur = (struct list_share *)malloc(sizeof(*cur)); - struct list_share *last; + struct map_entry *new_entry; - if (cur) + if (NULL == (new_entry = zalloc(sizeof(*new_entry)))) { - cur->str = (str ? strdup(str) : NULL); - cur->next = NULL; - - last = header->last; - if (last == NULL) - { - last = header; - } - - last->next = cur; - header->last = cur; + return; } -} - - -/********************************************************************* - * - * Function : enlist_unique_share - * - * Description : Append a string into a specified string list, - * if & only if it's not there already. - * - * Parameters : - * 1 : header = pointer to list 'dummy' header - * 2 : str = string to add to the list (maybe NULL) - * - * Returns : N/A - * - *********************************************************************/ -void enlist_unique_share(struct list_share *header, const char *str) -{ - struct list_share *last; - struct list_share *cur = header->next; + new_entry->name = nc ? strdup(name) : name; + new_entry->value = vc ? strdup(value) : value; + /* new_entry->next = NULL; - implied by zalloc */ - while (cur != NULL) + if (the_map->last) { - if ((cur->str != NULL) && (0 == strcmp(str, cur->str))) - { - /* Already there */ - return; - } - cur = cur->next; + the_map->last = the_map->last->next = new_entry; } - - cur = (struct list_share *)malloc(sizeof(*cur)); - - if (cur != NULL) + else { - cur->str = str; - cur->next = NULL; - - last = header->last; - if (last == NULL) - { - last = header; - } - last->next = cur; - header->last = cur; + the_map->last = the_map->first = new_entry; } -} - -/********************************************************************* - * - * Function : list_append_list_unique_share - * - * Description : Append a string list to another list - * - * Parameters : - * 1 : dest = pointer to destination for merge. Caller allocs. - * 2 : src = pointer to source for merge. - * - * Returns : N/A - * - *********************************************************************/ -void list_append_list_unique_share(struct list_share *dest, const struct list *src) -{ - struct list * cur = src->next; - - while (cur) - { - enlist_unique_share(dest, cur->str); - cur = cur->next; - } } /********************************************************************* * - * Function : list_remove_item_share + * Function : lookup * - * Description : Remove a string from a specified string list. + * Description : Look up an item with a given name in a map, and + * return its value * * Parameters : - * 1 : header = pointer to list 'dummy' header - * 2 : str = string to remove from the list + * 1 : name = name parameter to look for * - * Returns : Number of times it was removed. + * Returns : the value if found, else the empty string * *********************************************************************/ -int list_remove_item_share(struct list_share *header, const char *str) +const char *lookup(const struct map *the_map, const char *name) { - struct list_share *prev = header; - struct list_share *cur = prev->next; - int count = 0; + const struct map_entry *cur_entry = the_map->first; - while (cur != NULL) + while (cur_entry) { - if ((cur->str != NULL) && (0 == strcmp(str, cur->str))) + if (!strcmp(name, cur_entry->name)) { - count++; - - prev->next = cur->next; - free(cur); + return cur_entry->value; } - else - { - prev = cur; - } - cur = prev->next; + cur_entry = cur_entry->next; } - - header->last = prev; - - return count; + return ""; } /********************************************************************* * - * Function : list_remove_list_share + * Function : new_nap * - * Description : Remove all strings in one list from another list. - * This is currently a brute-force algorithm - * (it compares every pair of strings). + * Description : Create a new, empty map. * * Parameters : - * 1 : dest = list to change - * 2 : src = list of strings to remove * - * Returns : Total number of strings removed. + * Returns : A new, empty map, or NULL if out of memory. * *********************************************************************/ -int list_remove_list_share(struct list_share *dest, const struct list *src) +struct map *new_map(void) { - struct list *cur = src->next; - int count = 0; - - while (cur != NULL) - { - if (cur->str != NULL) - { - count += list_remove_item_share(dest, cur->str); - } - cur = cur->next; - } - - return count; + return (struct map *) zalloc(sizeof(struct map)); } /********************************************************************* * - * Function : list_duplicate_share + * Function : free_map * - * Description : Duplicate a string list + * Description : Free the memory occupied by a map and its + * depandant strings * * Parameters : - * 1 : dest = pointer to destination for copy. Caller allocs. - * 2 : src = pointer to source for copy. + * 1 : cur_entry = map to be freed. May be NULL. * * Returns : N/A * *********************************************************************/ -void list_duplicate_share(struct list_share *dest, const struct list *src) +void free_map(struct map *the_map) { - struct list * cur_src = src->next; - struct list_share * cur_dest = dest; + struct map_entry *cur_entry; + struct map_entry *next_entry; - memset(dest, '\0', sizeof(*dest)); + if (the_map == NULL) + { + return; + } - while (cur_src) + for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry) { - cur_dest = cur_dest->next = (struct list_share *)zalloc(sizeof(*cur_dest)); - if (cur_dest == NULL) - { - return; - } - cur_dest->str = cur_src->str; - cur_src = cur_src->next; + freez((char *)cur_entry->name); + freez((char *)cur_entry->value); + + next_entry = cur_entry->next; + free(cur_entry); } - dest->last = cur_dest; + the_map->first = the_map->last = NULL; + free(the_map); } + +/* + Local Variables: + tab-width: 3 + end: +*/