-const char list_rcs[] = "$Id: list.c,v NOT CHECKED IN $";
+const char list_rcs[] = "$Id: list.c,v 1.4 2001/06/29 13:30:22 oes Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/list.c,v $
*
* Revisions :
* $Log: list.c,v $
+ * 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.
+ *
*
*********************************************************************/
\f
}
+/*********************************************************************
+ *
+ * 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;
}
+/*********************************************************************
+ *
+ * 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 : first = first string to add to the list (maybe NULL)
+ * 3 : second = number of chars to use for uniqueness test
+ *
+ * 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
*
* 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.
while (cur)
{
- enlist_unique(dest, cur->str);
+ enlist_unique(dest, cur->str, 0);
cur = cur->next;
}
}
/*********************************************************************
*
- * 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 : 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
+ * Returns : pointer to extended map, or NULL if failiure
*
*********************************************************************/
-void enlist_share(struct list_share *header, const char *str)
+struct map *map(struct map *map, char *name, int nc, char *value, int vc)
{
- struct list_share *cur = (struct list_share *)malloc(sizeof(*cur));
- struct list_share *last;
+ struct map *cur;
- if (cur)
+ if (NULL == (cur = zalloc(sizeof(*cur))))
{
- cur->str = (str ? strdup(str) : NULL);
- cur->next = NULL;
+ return(NULL);
+ }
- last = header->last;
- if (last == NULL)
- {
- last = header;
- }
+ cur->name = nc ? strdup(name) : name;
+ cur->value = vc ? strdup(value) : value;
+ cur->next = map;
- last->next = cur;
- header->last = cur;
- }
+ return(cur);
}
/*********************************************************************
*
- * Function : enlist_unique_share
+ * Function : lookup
*
- * Description : Append a string into a specified string list,
- * if & only if it's not there already.
+ * 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 add to the list (maybe NULL)
+ * 1 : name = name parameter to look for
*
- * Returns : N/A
+ * Returns : the value if found, else the empty string
*
*********************************************************************/
-void enlist_unique_share(struct list_share *header, const char *str)
+char *lookup(struct map *map, char *name)
{
- struct list_share *last;
- struct list_share *cur = header->next;
+ struct map *p = map;
- while (cur != NULL)
+ while (p)
{
- if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
+ if (!strcmp(name, p->name))
{
- /* Already there */
- return;
+ return p->value;
}
- cur = cur->next;
+ p = p->next;
}
+ return "";
- cur = (struct list_share *)malloc(sizeof(*cur));
-
- if (cur != NULL)
- {
- cur->str = str;
- cur->next = NULL;
-
- last = header->last;
- if (last == NULL)
- {
- last = header;
- }
- last->next = cur;
- header->last = cur;
- }
}
/*********************************************************************
*
- * Function : list_append_list_unique_share
+ * Function : free_map
*
- * Description : Append a string list to another list
+ * Description : Free the memory occupied by a map and its
+ * depandant strings
*
* Parameters :
- * 1 : dest = pointer to destination for merge. Caller allocs.
- * 2 : src = pointer to source for merge.
+ * 1 : list = list to bee freed
*
* 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
- *
- * Description : Remove a string from a specified string list.
- *
- * Parameters :
- * 1 : header = pointer to list 'dummy' header
- * 2 : str = string to remove from the list
- *
- * Returns : Number of times it was removed.
- *
- *********************************************************************/
-int list_remove_item_share(struct list_share *header, const char *str)
+void free_map(struct map *map)
{
- struct list_share *prev = header;
- struct list_share *cur = prev->next;
- int count = 0;
+ struct map *p = map;
- while (cur != NULL)
+ while (p)
{
- if ((cur->str != NULL) && (0 == strcmp(str, cur->str)))
- {
- count++;
-
- prev->next = cur->next;
- free(cur);
- }
- else
- {
- prev = cur;
- }
- cur = prev->next;
- }
-
- header->last = prev;
-
- return count;
-}
+ free(p->name);
+ free(p->value);
-
-/*********************************************************************
- *
- * Function : list_remove_list_share
- *
- * Description : Remove all strings in one list from another list.
- * This is currently a brute-force algorithm
- * (it compares every pair of strings).
- *
- * Parameters :
- * 1 : dest = list to change
- * 2 : src = list of strings to remove
- *
- * Returns : Total number of strings removed.
- *
- *********************************************************************/
-int list_remove_list_share(struct list_share *dest, const struct list *src)
-{
- 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;
+ map = p->next;
+ free(p);
+ p = map;
}
- return count;
}
-/*********************************************************************
- *
- * Function : list_duplicate_share
- *
- * Description : Duplicate a string list
- *
- * Parameters :
- * 1 : dest = pointer to destination for copy. Caller allocs.
- * 2 : src = pointer to source for copy.
- *
- * Returns : N/A
- *
- *********************************************************************/
-void list_duplicate_share(struct list_share *dest, const struct list *src)
-{
- struct list * cur_src = src->next;
- struct list_share * cur_dest = dest;
-
- memset(dest, '\0', sizeof(*dest));
-
- while (cur_src)
- {
- 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;
- }
-
- dest->last = cur_dest;
-
-}
-
+/*
+ Local Variables:
+ tab-width: 3
+ end:
+*/