#define USE_XML_ATTR_DATA
#include <xml/attrdata.h>
#include <xml/attrlist.h>
#include <string.h>

#define ___ {
#define ____ }

/* AttrData */
xml_AttrData* 
xml_attr_data_alloc (void) 
{
    return g_new0 (xml_AttrData, 1);
}
xml_AttrData*
xml_attr_data_new0 (gchar* name, gchar* value)
{
    xml_AttrData* data = xml_attr_data_alloc ();
    data->name = name;
    data->value = value;
    return data;
}
xml_AttrData*
xml_attr_data_new1 (const gchar* name, gchar* value)
{
    return xml_attr_data_new0 (g_strdup (name), value);
}
xml_AttrData*
xml_attr_data_new2 (const gchar* name, const gchar* value)
{
    return xml_attr_data_new0 (g_strdup (name), g_strdup (value));
}
void
xml_attr_data_free (xml_AttrData* data)
{
    if (! data) return;
    g_free (data->name);
    g_free (data->value);
    g_free (data);
}
gchar* 
xml_attr_data_free1 (xml_AttrData* data)
{
    if (! data) return 0;
    g_free (data->name);
    ___ gchar* value = data->value;
    g_free (data);
    return value;
    ____;
}
xml_AttrData*
xml_attr_data_copy (xml_AttrData* data)
{
    if (! data) return data;
    ___ xml_AttrData* attr = xml_attr_data_alloc ();
    attr->name = g_strdup (data->name);
    attr->value = g_strdup (data->value);
    return attr;
    ____;
}
xml_AttrList*    xml_attr_list_new0 (gchar* key, gchar* value)
{
    xml_AttrList* attr = xml_attr_list_alloc_link ();
    attr->data = xml_attr_data_new0 (key, value);
    return attr;
}
xml_AttrList*    xml_attr_list_new1 (const gchar* key, gchar* value)
{
    xml_AttrList* attr = xml_attr_list_alloc_link ();
    attr->data = xml_attr_data_new1 (key, value);
    return attr;
}
xml_AttrList*    xml_attr_list_new2 (const gchar* key, const gchar* value)
{
    xml_AttrList* attr = xml_attr_list_alloc_link ();
    attr->data = xml_attr_data_new2 (key, value);
    return attr;
}
/* alloc */
xml_AttrList*     xml_attr_list_alloc       (void)
{
    xml_AttrList* attr = xml_attr_list_alloc_link();
    attr->data = xml_attr_data_alloc ();
    return attr;
}
void              xml_attr_list_free      (xml_AttrList   *list)
{
    if (! list) return;
    ___ xml_AttrList* attr = list;
    for (; attr ; attr = attr->next)
    
{
	xml_attr_data_free (attr->data);
    }
; ____; xml_attr_list_free_link (list); /* chains links into free_list */ }
xml_AttrList*     xml_attr_list_free_1      (xml_AttrList   *list)
{
    if (! list) return list;
    ___ xml_AttrList* next = list->next;
    xml_attr_data_free (list->data);
    xml_attr_list_free_link_1 (list);
    return next; ____;
}
/*
   when an old data did already exists under the same name then
   the old data is free'd - so it actually is a _set operation.
 */
xml_AttrList*     xml_attr_list_add     (xml_AttrList  *list,
					 xml_AttrData  *data)
{
    if (! data) return (xml_AttrList*) data;
    if (! list || ! data->name) return xml_attr_list_prepend (list, data);
    
    ___ xml_AttrList* attr = list;
    while (1)
    
{
	gint cmp = strcmp (attr->data->name, data->name);
	if (cmp < 0) 
{ 
	    if (attr->next) 
{ attr = attr->next; continue; }
/* append */ attr->next = xml_attr_list_alloc_link (); attr->next->prev = attr; attr->next->data = data; return list; }
if (cmp == 0)
{
	    xml_attr_data_free (attr->data); 
	    attr->data = data;
	    return list;
	}
/* (cmp > 0) */ return xml_attr_list_insert_before (list, attr, data); }
____; }
/*
   when an old data did already exists under the same name then
   the new data is still inserted, after the old one.
 */
xml_AttrList*     xml_attr_list_insert       (xml_AttrList  *list,
					      xml_AttrData  *data)
{
    if (! data) return (xml_AttrList*) data;
    if (! list || ! data->name) return xml_attr_list_prepend (list, data);
    
    ___ xml_AttrList* attr = list;
    while (1)
    
{
	gint cmp = strcmp (attr->data->name, data->name);
	if (cmp <= 0) 
{ 
	    if (attr->next) 
{ attr = attr->next; continue; }
/* append */ attr->next = xml_attr_list_alloc_link (); attr->next->prev = attr; attr->next->data = data; return list; }
/* (cmp > 0) */ return xml_attr_list_insert_before (list, attr, data); }
____; }
xml_AttrList*     xml_attr_list_delete   (xml_AttrList   *list,
					  const gchar*   name)
{
    xml_AttrList* attr = xml_attr_list_find_name (list, name);
    if (! attr) return list;
    xml_attr_data_free (attr->data);
    return xml_attr_list_delete_link (list, attr);
}
xml_AttrList*     xml_attr_list_copy         (xml_AttrList     *list)
{
    list = xml_attr_list_copy_links (list);
    ___ xml_AttrList* attr = list;
    for (; attr ; attr = attr->next)
    
{
	attr->data = xml_attr_data_copy (attr->data);
    }
; ____; return list; }
static int custom (xml_AttrData* data, const gchar* name)
{
    return strcmp (data->name, name);
}
xml_AttrList*     xml_attr_list_find_name     (xml_AttrList     *list,
					       const gchar*     name)
{
    return xml_attr_list_find_custom (list, name, (GCompareFunc) custom);
}
/* 
   Local variables:
   c-file-style: "stroustrup"
   End:
 */