-const char list_rcs[] = "$Id: list.c,v 1.1 2001/05/31 21:11:53 jongfoster Exp $";
+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 $
*
* 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,
#include <ctype.h>
#include <string.h>
+#include <assert.h>
+
#ifndef _WIN32
#include <unistd.h>
#endif
const char list_h_rcs[] = LIST_H_VERSION;
+
/*********************************************************************
*
* Function : enlist
}
+/*********************************************************************
+ *
+ * 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 : 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
*
* 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
struct list *p;
char *ret = NULL;
char *s;
- int size;
-
- size = 0;
+ int size = 2;
for (p = h->next; p ; p = p->next)
{
*s++ = '\r'; *s++ = '\n';
}
}
+ *s++ = '\r'; *s++ = '\n';
return(ret);
while (cur)
{
- enlist_unique(dest, cur->str);
+ enlist_unique(dest, cur->str, 0);
cur = cur->next;
}
}
+
+/*********************************************************************
+ *
+ * Function : map
+ *
+ * Description : Add a mapping from given name to given value to a
+ * given map.
+ *
+ * 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 : 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 map(struct map *the_map, const char *name, int nc, const char *value, int vc)
+{
+ struct map_entry *new_entry;
+
+ if (NULL == (new_entry = zalloc(sizeof(*new_entry))))
+ {
+ return;
+ }
+
+ new_entry->name = nc ? strdup(name) : name;
+ new_entry->value = vc ? strdup(value) : value;
+ /* new_entry->next = NULL; - implied by zalloc */
+
+ if (the_map->last)
+ {
+ the_map->last = the_map->last->next = new_entry;
+ }
+ else
+ {
+ the_map->last = the_map->first = new_entry;
+ }
+
+}
+
+
+/*********************************************************************
+ *
+ * Function : lookup
+ *
+ * Description : Look up an item with a given name in a map, and
+ * return its value
+ *
+ * Parameters :
+ * 1 : name = name parameter to look for
+ *
+ * Returns : the value if found, else the empty string
+ *
+ *********************************************************************/
+const char *lookup(const struct map *the_map, const char *name)
+{
+ const struct map_entry *cur_entry = the_map->first;
+
+ while (cur_entry)
+ {
+ if (!strcmp(name, cur_entry->name))
+ {
+ return cur_entry->value;
+ }
+ cur_entry = cur_entry->next;
+ }
+ return "";
+}
+
+
+/*********************************************************************
+ *
+ * Function : new_nap
+ *
+ * Description : Create a new, empty map.
+ *
+ * Parameters :
+ *
+ * Returns : A new, empty map, or NULL if out of memory.
+ *
+ *********************************************************************/
+struct map *new_map(void)
+{
+ return (struct map *) zalloc(sizeof(struct map));
+}
+
+
+/*********************************************************************
+ *
+ * Function : free_map
+ *
+ * Description : Free the memory occupied by a map and its
+ * depandant strings
+ *
+ * Parameters :
+ * 1 : cur_entry = map to be freed. May be NULL.
+ *
+ * Returns : N/A
+ *
+ *********************************************************************/
+void free_map(struct map *the_map)
+{
+ struct map_entry *cur_entry;
+ struct map_entry *next_entry;
+
+ if (the_map == NULL)
+ {
+ return;
+ }
+
+ for (cur_entry = the_map->first; cur_entry != NULL; cur_entry = next_entry)
+ {
+ freez((char *)cur_entry->name);
+ freez((char *)cur_entry->value);
+
+ next_entry = cur_entry->next;
+ free(cur_entry);
+ }
+
+ the_map->first = the_map->last = NULL;
+
+ free(the_map);
+}
+
+
/*
Local Variables:
tab-width: 3