/*
 * XML Catalog Manager (xmlcatmgr)
 * $Id: xmlnode.h,v 1.5 2004/05/02 09:40:42 jmmv Exp $
 *
 * Copyright (c) 2003, 2004 Julio M. Merino Vidal.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name of the author nor the names of contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef XMLCATMGR_XMLNODE_H
#define XMLCATMGR_XMLNODE_H

#include "linklist.h"

LINKLIST_HEAD(xmlattrs, xmlattr);
struct xmlattr {
    LINKLIST_ENTRY(xmlattr);

    char *xa_name;
    char *xa_value;
};

#define XMLATTR_NAME(attr) ((attr)->xa_name)
#define XMLATTR_VALUE(attr) ((attr)->xa_value)

LINKLIST_HEAD(xmlnodes, xmlnode);
struct xmlnode {
    LINKLIST_ENTRY(xmlnode);

#define XMLNODE_TYPE_ROOT 0
#define XMLNODE_TYPE_ELEMENT 1
#define XMLNODE_TYPE_COMMENT 2
#define XMLNODE_TYPE_TEXT 3
    int xn_type;

    char *xn_tag;
    char *xn_text;
    struct xmlnode *xn_parent;
    struct xmlattrs xn_attrs;
    struct xmlnodes xn_childs;
};

#define XMLNODE_FOREACH_ATTR(iter, node) \
    LINKLIST_FOREACH(iter, &((node)->xn_attrs))

#define XMLNODE_FOREACH_CHILD(iter, node) \
    LINKLIST_FOREACH(iter, &((node)->xn_childs))

#define XMLNODE_TYPE(node) ((node)->xn_type)
#define XMLNODE_TAG(node) ((node)->xn_tag)
#define XMLNODE_TEXT(node) ((node)->xn_text)

#define XMLNODE_APPEND_ATTR(node, attr) \
    LINKLIST_APPEND(&((node)->xn_attrs), attr)
#define XMLNODE_APPEND_CHILD(node, child) \
    (child)->xn_parent = node; \
    LINKLIST_APPEND(&((node)->xn_childs), child);

#define XMLNODE_PREPEND_CHILD(node, child) \
    (child)->xn_parent = node; \
    LINKLIST_PREPEND(&((node)->xn_childs), child);

#define XMLNODE_DETACH(node) \
    assert((node)->xn_parent != NULL); \
    LINKLIST_REMOVE(&((node)->xn_parent->xn_childs), node)

struct xmlattr *xmlattr_new(char *, char *);
void xmlattr_free(struct xmlattr *);
bool xmlattr_write(struct xmlattr *, FILE *);
struct xmlnode *xmlnode_new(int, char *);
void xmlnode_free(struct xmlnode *);
char *xmlnode_get_attr_value(struct xmlnode *, const char *);
void xmlnode_set_text(struct xmlnode *, char *);
void xmlnode_become_root(struct xmlnode *);
bool xmlnode_write(struct xmlnode *, FILE *);

#endif /* XMLCATMGR_XMLNODE_H */

/*
 * Local Variables: ***
 * mode: c ***
 * c-file-style: "stroustrup" ***
 * End: ***
 * vim: syntax=c:expandtab:shiftwidth=4:softtabstop=4
 */
