Projekt

Allgemein

Profil

Herunterladen (16,7 KB) Statistiken
| Zweig: | Markierung: | Revision:
d8f33628 aquamaniac
/***************************************************************************
$RCSfile$
-------------------
cvs : $Id$
begin : Sat Jun 28 2003
copyright : (C) 2003 by Martin Preuss
email : martin@libchipcard.de

***************************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA *
* *
***************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

3ca7a382 aquamaniac
#define DISABLE_DEBUGLOG

9b7237ac aquamaniac
#include "xml_p.h"
#include "gwenhyfwar/debug.h"
#include "gwenhyfwar/misc.h"
d8f33628 aquamaniac
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>



9b7237ac aquamaniac
GWEN_XMLPROPERTY *GWEN_XMLProperty_new(const char *name, const char *value){
GWEN_XMLPROPERTY *p;

GWEN_NEW_OBJECT(GWEN_XMLPROPERTY, p);
d8f33628 aquamaniac
if (name)
p->name=strdup(name);
if (value)
p->value=strdup(value);
return p;
}


9b7237ac aquamaniac
void GWEN_XMLProperty_free(GWEN_XMLPROPERTY *p){
d8f33628 aquamaniac
if (p) {
free(p->name);
free(p->value);
free(p);
}
}


9b7237ac aquamaniac
GWEN_XMLPROPERTY *GWEN_XMLProperty_dup(GWEN_XMLPROPERTY *p){
return GWEN_XMLProperty_new(p->name, p->value);
d8f33628 aquamaniac
}


9b7237ac aquamaniac
void GWEN_XMLProperty_add(GWEN_XMLPROPERTY *p, GWEN_XMLPROPERTY **head){
GWEN_LIST_ADD(GWEN_XMLPROPERTY, p, head);
d8f33628 aquamaniac
}


9b7237ac aquamaniac
void GWEN_XMLProperty_del(GWEN_XMLPROPERTY *p, GWEN_XMLPROPERTY **head){
GWEN_LIST_DEL(GWEN_XMLPROPERTY, p, head);
d8f33628 aquamaniac
}


9b7237ac aquamaniac
void GWEN_XMLProperty_freeAll(GWEN_XMLPROPERTY *p) {
d8f33628 aquamaniac
while(p) {
9b7237ac aquamaniac
GWEN_XMLPROPERTY *next;
d8f33628 aquamaniac
next=p->next;
9b7237ac aquamaniac
GWEN_XMLProperty_free(p);
d8f33628 aquamaniac
p=next;
} /* while */
}




9b7237ac aquamaniac
GWEN_XMLNODE *GWEN_XMLNode_new(GWEN_XMLNODE_TYPE t, const char *data){
GWEN_XMLNODE *n;
d8f33628 aquamaniac
9b7237ac aquamaniac
n=(GWEN_XMLNODE *)malloc(sizeof(GWEN_XMLNODE));
d8f33628 aquamaniac
assert(n);
9b7237ac aquamaniac
memset(n,0,sizeof(GWEN_XMLNODE));
d8f33628 aquamaniac
n->type=t;
if (data)
n->data=strdup(data);
return n;
}


9b7237ac aquamaniac
void GWEN_XMLNode_free(GWEN_XMLNODE *n){
d8f33628 aquamaniac
if (n) {
9b7237ac aquamaniac
GWEN_XMLProperty_freeAll(n->properties);
d8f33628 aquamaniac
free(n->data);
9b7237ac aquamaniac
GWEN_XMLNode_freeAll(n->child);
d8f33628 aquamaniac
free(n);
}
}


9b7237ac aquamaniac
void GWEN_XMLNode_freeAll(GWEN_XMLNODE *n){
d8f33628 aquamaniac
while(n) {
9b7237ac aquamaniac
GWEN_XMLNODE *next;
d8f33628 aquamaniac
next=n->next;
9b7237ac aquamaniac
GWEN_XMLNode_free(n);
d8f33628 aquamaniac
n=next;
} /* while */
}


9b7237ac aquamaniac
GWEN_XMLNODE *GWEN_XMLNode_dup(GWEN_XMLNODE *n){
GWEN_XMLNODE *nn, *cn, *ncn;
GWEN_XMLPROPERTY *p;
d8f33628 aquamaniac
/* duplicate node itself */
9b7237ac aquamaniac
nn=GWEN_XMLNode_new(n->type, n->data);
d8f33628 aquamaniac
/* duplicate properties */
p=n->properties;
while(p) {
9b7237ac aquamaniac
GWEN_XMLPROPERTY *np;
d8f33628 aquamaniac
9b7237ac aquamaniac
np=GWEN_XMLProperty_dup(p);
GWEN_XMLProperty_add(np, &(nn->properties));
d8f33628 aquamaniac
p=p->next;
} /* while */

/* duplicate children */
cn=n->child;
while(cn) {
9b7237ac aquamaniac
ncn=GWEN_XMLNode_dup(cn);
GWEN_XMLNode_add(ncn, &(nn->child));
d8f33628 aquamaniac
ncn->parent=nn;
cn=cn->next;
} /* while */

return nn;
}


9b7237ac aquamaniac
void GWEN_XMLNode_add(GWEN_XMLNODE *n, GWEN_XMLNODE **head){
GWEN_LIST_ADD(GWEN_XMLNODE, n, head);
d8f33628 aquamaniac
}


9b7237ac aquamaniac
void GWEN_XMLNode_del(GWEN_XMLNODE *n, GWEN_XMLNODE **head){
GWEN_LIST_DEL(GWEN_XMLNODE, n, head);
d8f33628 aquamaniac
n->parent=0;
}


9b7237ac aquamaniac
const char *GWEN_XMLNode_GetProperty(GWEN_XMLNODE *n, const char *name,
const char *defaultValue){
GWEN_XMLPROPERTY *p;
d8f33628 aquamaniac
assert(n);
assert(name);
p=n->properties;
while(p) {
assert(p->name);
if (strcasecmp(p->name, name)==0)
break;
p=p->next;
} /* while */

if (p) {
if (p->value)
return p->value;
}
return defaultValue;
}


9b7237ac aquamaniac
void GWEN_XMLNode_SetProperty(GWEN_XMLNODE *n,
const char *name, const char *value){
GWEN_XMLPROPERTY *p;
d8f33628 aquamaniac
p=n->properties;
while(p) {
assert(p->name);
if (strcasecmp(p->name, name)==0)
break;
p=p->next;
} /* while */

if (p) {
free(p->value);
if (value)
p->value=strdup(value);
else
p->value=0;
}
else {
9b7237ac aquamaniac
p=GWEN_XMLProperty_new(name, value);
GWEN_XMLProperty_add(p, &(n->properties));
d8f33628 aquamaniac
}
}


9b7237ac aquamaniac
const char *GWEN_XMLNode_GetData(GWEN_XMLNODE *n){
d8f33628 aquamaniac
assert(n);
return n->data;
}


9b7237ac aquamaniac
void GWEN_XMLNode_SetData(GWEN_XMLNODE *n, const char *data){
d8f33628 aquamaniac
assert(n);
free(n->data);
if (data)
n->data=strdup(data);
else
n->data=0;
}


9b7237ac aquamaniac
GWEN_XMLNODE *GWEN_XMLNode_GetChild(GWEN_XMLNODE *n){
d8f33628 aquamaniac
assert(n);
return n->child;
}


9b7237ac aquamaniac
GWEN_XMLNODE *GWEN_XMLNode_GetParent(GWEN_XMLNODE *n){
d8f33628 aquamaniac
assert(n);
return n->parent;
}


9b7237ac aquamaniac
void GWEN_XMLNode_AddChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child){
d8f33628 aquamaniac
assert(n);
9b7237ac aquamaniac
GWEN_XMLNode_add(child, &(n->child));
d8f33628 aquamaniac
child->parent=n;
}


9b7237ac aquamaniac
int GWEN_XML__ReadWord(GWEN_BUFFEREDIO *bio,
char chr,
const char *delims,
char *buffer,
unsigned int size) {
d8f33628 aquamaniac
int inQuote;

assert(size);
inQuote=0;
size--;
buffer[0]=0;

while(1) {
/* get character, if needed */
if (chr==0) {
9b7237ac aquamaniac
if (GWEN_BufferedIO_CheckEOF(bio))
d8f33628 aquamaniac
break;
9b7237ac aquamaniac
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
DBG_ERROR(0, "Error on ReadChar");
d8f33628 aquamaniac
return -1;
}
}
if (iscntrl(chr))
chr=' ';

if (inQuote) {
if (chr=='"') {
inQuote=0;
break;
}
else {
if (size<1) {
9b7237ac aquamaniac
DBG_ERROR(0, "Word too long");
d8f33628 aquamaniac
return -1;
}
*buffer=chr;
buffer++;
size--;
}
}
else {
if (chr=='"') {
inQuote=1;
}
else if (strchr(delims, chr)) {
break;
}
else if (chr=='<') {
9b7237ac aquamaniac
DBG_ERROR(0, "No tags inside a tag definition allowed");
d8f33628 aquamaniac
return -1;
}
else {
if (size<1) {
9b7237ac aquamaniac
DBG_ERROR(0, "Word too long");
d8f33628 aquamaniac
return -1;
}
*buffer=chr;
buffer++;
size--;
}
}
chr=0;
} /* while */
*buffer=0;

return chr;
}



0200e1e7 aquamaniac
int GWEN_XML_Parse(GWEN_XMLNODE *n, GWEN_BUFFEREDIO *bio,
unsigned int flags) {
9b7237ac aquamaniac
GWEN_XMLNODE *path[GWEN_XML_MAX_DEPTH];
d8f33628 aquamaniac
int currDepth;
int chr;
int isEndTag;
int eofMet;
int isComment;

currDepth=0;
chr=0;

9b7237ac aquamaniac
while (!GWEN_BufferedIO_CheckEOF(bio)) {
d8f33628 aquamaniac
/* read char (if none set) but skip blanks */
if (chr==0) {
9b7237ac aquamaniac
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
DBG_ERROR(0, "Error on BufferedIO_ReadChar");
d8f33628 aquamaniac
return -1;
}
}
eofMet=0;
while(isspace(chr)) {
9b7237ac aquamaniac
if (GWEN_BufferedIO_CheckEOF(bio)) {
d8f33628 aquamaniac
eofMet=1;
break;
}
9b7237ac aquamaniac
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
DBG_ERROR(0, "Error on BufferedIO_ReadChar");
d8f33628 aquamaniac
return -1;
}
}
if (eofMet)
break;

if (chr=='<') {
9b7237ac aquamaniac
char tagname[GWEN_XML_MAX_TAGNAMELEN];
d8f33628 aquamaniac
char *p;

isEndTag=0;

/* we have a tag */
9b7237ac aquamaniac
chr=GWEN_XML__ReadWord(bio, 0, " ><", tagname, sizeof(tagname));
d8f33628 aquamaniac
if (chr<0)
return -1;

p=tagname;
if (*p=='/') {
isEndTag=1;
p++;
}
9b7237ac aquamaniac
DBG_DEBUG(0, "Found tag \"%s\"", tagname);
d8f33628 aquamaniac
isComment=0;
if (strlen(p)>=3)
if (strncmp(p,"!--",3)==0)
isComment=1;
if (isComment) {
9b7237ac aquamaniac
char comment[GWEN_XML_MAX_REMARKLEN];
d8f33628 aquamaniac
int comlen;
9b7237ac aquamaniac
GWEN_XMLNODE *newNode;
d8f33628 aquamaniac
comlen=0;
comment[0]=0;

9b7237ac aquamaniac
DBG_DEBUG(0, "Found comment");
d8f33628 aquamaniac
/* we have a remark tag, so read it over */
while(1) {
if (chr==0) {
9b7237ac aquamaniac
if (GWEN_BufferedIO_CheckEOF(bio)) {
DBG_ERROR(0, "Unexpected EOF within comment");
d8f33628 aquamaniac
return -1;
}
9b7237ac aquamaniac
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
return -1;
}
0200e1e7 aquamaniac
}

if (comlen>=sizeof(comment)) {
DBG_ERROR(0, "Comment too long !");
return -1;
}
d8f33628 aquamaniac
comment[comlen++]=chr;

if (comlen>=3) {
if (strncmp(comment+comlen-3,"-->",3)==0) {
comlen-=3;
comment[comlen]=0;
0200e1e7 aquamaniac
break;
}
else {
if (!(flags & GWEN_XML_FLAGS_READ_COMMENTS)) {
DBG_VERBOUS(0, "Clipping comment to 2 bytes");
memmove(comment, comment+comlen-2, 2);
comlen=2;
}
}
}
chr=0;
d8f33628 aquamaniac
} /* while */

0200e1e7 aquamaniac
/* create new node */
DBG_VERBOUS(0, "Comment finished");
if (flags & GWEN_XML_FLAGS_READ_COMMENTS) {
newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeComment,
comment);
GWEN_XMLNode_add(newNode, &(n->child));
newNode->parent=n;
DBG_DEBUG(0, "Added comment: \"%s\"", comment);
}
else {
DBG_DEBUG(0, "Skip comment");
}
d8f33628 aquamaniac
} /* if remark */
else {
/* handle tagname */
if (isEndTag) {
/* handle endtag */
if (currDepth<1) {
9b7237ac aquamaniac
DBG_ERROR(0, "More endtags than start tags !");
d8f33628 aquamaniac
return -1;
}
if (strcasecmp(n->data, p)!=0) {
9b7237ac aquamaniac
DBG_ERROR(0, "endtag \"%s\" does not match last start tag (\"%s\")",
d8f33628 aquamaniac
tagname, n->data);
return -1;
}
/* surface */
n=path[currDepth-1];
currDepth--;
if (currDepth==0) {
9b7237ac aquamaniac
DBG_DEBUG(0, "One node done");
d8f33628 aquamaniac
return 0;
}
}
else {
/* this is a start tag */
9b7237ac aquamaniac
GWEN_XMLNODE *newNode;
char varname[GWEN_XML_MAX_VARNAMELEN];
char value[GWEN_XML_MAX_VALUELEN];
d8f33628 aquamaniac
if (*p) {
int j;

j=strlen(p)-1;
if (p[j]=='/') {
if (chr!='>') {
9b7237ac aquamaniac
DBG_ERROR(0, "\"/\" only allowed just before \">\"");
d8f33628 aquamaniac
return -1;
}
p[j]=0;
isEndTag=1;
}
}

9b7237ac aquamaniac
newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeTag, p);
d8f33628 aquamaniac
while (chr!='>' && chr!='/') {
varname[0]=0;
value[0]=0;

/* skip blanks */
chr=0;
9b7237ac aquamaniac
while(!GWEN_BufferedIO_CheckEOF(bio)) {
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
if (!isspace(chr) && !iscntrl(chr))
break;
}
if (chr==0) {
9b7237ac aquamaniac
DBG_ERROR(0, "unexpected EOF");
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}

if (chr=='>' || chr=='/')
break;

/* read possibly following var */
9b7237ac aquamaniac
chr=GWEN_XML__ReadWord(bio, chr, " =/>", varname, sizeof(varname));
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}

9b7237ac aquamaniac
DBG_DEBUG(0, "Found property \"%s\"", varname);
d8f33628 aquamaniac
/* skip blanks */
if (isspace(chr)) {
9b7237ac aquamaniac
while(!GWEN_BufferedIO_CheckEOF(bio)) {
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
if (!isspace(chr) && !iscntrl(chr))
break;
}
}

if (chr=='=') {
chr=0;
/* skip blanks */
9b7237ac aquamaniac
while(!GWEN_BufferedIO_CheckEOF(bio)) {
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
if (!isspace(chr))
break;
}
if (chr==0) {
9b7237ac aquamaniac
DBG_ERROR(0, "Value expected for property \"%s\"",
d8f33628 aquamaniac
varname);
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}

if (chr=='>' || chr=='/') {
9b7237ac aquamaniac
DBG_ERROR(0, "Value expected for property \"%s\"",
d8f33628 aquamaniac
varname);
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}

/* read value */
9b7237ac aquamaniac
chr=GWEN_XML__ReadWord(bio, chr, " />", value, sizeof(value));
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
9b7237ac aquamaniac
DBG_DEBUG(0, "Found value \"%s\"", value);
d8f33628 aquamaniac
} /* if value follows */

if (varname[0]) {
/* add property */
9b7237ac aquamaniac
GWEN_XMLPROPERTY *newProp;
d8f33628 aquamaniac
9b7237ac aquamaniac
newProp=GWEN_XMLProperty_new(varname,
value[0]?value:0);
GWEN_XMLProperty_add(newProp, &(newNode->properties));
d8f33628 aquamaniac
} /* if varname */
} /* while vars follow */

if (chr=='/') {
isEndTag=1;

9b7237ac aquamaniac
if (GWEN_BufferedIO_CheckEOF(bio)) {
DBG_ERROR(0, "\">\" expected");
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}

9b7237ac aquamaniac
chr=GWEN_BufferedIO_ReadChar(bio);
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
DBG_ERROR(0, "Error on ReadChar");
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
}

if (chr!='>') {
9b7237ac aquamaniac
DBG_ERROR(0, "\">\" expected");
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}

/* ok, now the tag is complete, add it */
9b7237ac aquamaniac
if (currDepth>=GWEN_XML_MAX_DEPTH) {
DBG_ERROR(0, "Maximum depth exceeded");
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
9b7237ac aquamaniac
GWEN_XMLNode_add(newNode, &(n->child));
d8f33628 aquamaniac
newNode->parent=n;
9b7237ac aquamaniac
DBG_DEBUG(0, "Added node \"%s\"", newNode->data);
d8f33628 aquamaniac
if (!isEndTag) {
/* only dive if this tag is not immediately ended */
path[currDepth++]=n;
n=newNode;
}
else {
/* immediate endTag, if depth is 0: done */
if (currDepth==0) {
9b7237ac aquamaniac
DBG_DEBUG(0, "One node done");
d8f33628 aquamaniac
return 0;
}
}
} /* if start tag */
} /* if no remark */

chr=0; /* make begin of loop read new char */
} /* if "<" */
else {
/* add data to current tag */
9b7237ac aquamaniac
GWEN_XMLNODE *newNode;
char data[GWEN_XML_MAX_DATALEN];
d8f33628 aquamaniac
9b7237ac aquamaniac
chr=GWEN_XML__ReadWord(bio, chr, "<", data, sizeof(data));
d8f33628 aquamaniac
if (chr<0) {
9b7237ac aquamaniac
GWEN_XMLNode_free(newNode);
d8f33628 aquamaniac
return -1;
}
9b7237ac aquamaniac
newNode=GWEN_XMLNode_new(GWEN_XMLNodeTypeData, data);
DBG_DEBUG(0, "Added data \"%s\"", data);
GWEN_XMLNode_add(newNode, &(n->child));
d8f33628 aquamaniac
newNode->parent=n;
}
/* do not set chr=0, because we may already have the next char ('<') */
} /* while !eof */

if (currDepth!=0) {
9b7237ac aquamaniac
DBG_ERROR(0, "%d tags are still open", currDepth);
d8f33628 aquamaniac
return -1;
}

return 0;
}


0200e1e7 aquamaniac
int GWEN_XML_ReadFile(GWEN_XMLNODE *n, const char *filepath,
unsigned int flags){
9b7237ac aquamaniac
GWEN_BUFFEREDIO *dm;
d8f33628 aquamaniac
int fd;

fd=open(filepath, O_RDONLY);
if (fd==-1) {
9b7237ac aquamaniac
DBG_ERROR(0, "open(%s): %s",
d8f33628 aquamaniac
filepath,
strerror(errno));
return -1;
}

9b7237ac aquamaniac
dm=GWEN_BufferedIO_File_new(fd);
GWEN_BufferedIO_SetReadBuffer(dm,0,1024);
d8f33628 aquamaniac
9b7237ac aquamaniac
while(!GWEN_BufferedIO_CheckEOF(dm)) {
0200e1e7 aquamaniac
if (GWEN_XML_Parse(n, dm, flags)) {
9b7237ac aquamaniac
DBG_ERROR(0, "Error parsing");
GWEN_BufferedIO_Close(dm);
GWEN_BufferedIO_free(dm);
d8f33628 aquamaniac
return -1;
}
} /* while */

9b7237ac aquamaniac
GWEN_BufferedIO_Close(dm);
GWEN_BufferedIO_free(dm);
d8f33628 aquamaniac
return 0;
}


9b7237ac aquamaniac
GWEN_XMLNODE_TYPE GWEN_XMLNode_GetType(GWEN_XMLNODE *n){
d8f33628 aquamaniac
assert(n);
return n->type;
}


9b7237ac aquamaniac
GWEN_XMLNODE *GWEN_XMLNode_Next(GWEN_XMLNODE *n) {
d8f33628 aquamaniac
assert(n);
return n->next;
}


9b7237ac aquamaniac
void GWEN_XMLNode_Dump(GWEN_XMLNODE *n, FILE *f, int ind) {
GWEN_XMLPROPERTY *p;
GWEN_XMLNODE *c;
d8f33628 aquamaniac
int i;

assert(n);

for(i=0; i<ind; i++)
fprintf(f, " ");

9b7237ac aquamaniac
if (n->type==GWEN_XMLNodeTypeTag) {
d8f33628 aquamaniac
if (n->data)
fprintf(f, "<%s", n->data);
else
fprintf(f, "<UNKNOWN");
p=n->properties;
while (p) {
4e94dfc9 aquamaniac
fprintf(f, " %s=\"%s\"", p->name, p->value);
d8f33628 aquamaniac
p=p->next;
}
fprintf(f, ">\n");
c=n->child;
while(c) {
9b7237ac aquamaniac
GWEN_XMLNode_Dump(c, f, ind+2);
d8f33628 aquamaniac
c=c->next;
}
for(i=0; i<ind; i++)
fprintf(f, " ");
if (n->data)
fprintf(f, "</%s>\n", n->data);
else
fprintf(f, "</UNKNOWN>\n");
}
9b7237ac aquamaniac
else if (n->type==GWEN_XMLNodeTypeData) {
d8f33628 aquamaniac
if (n->data) {
fprintf(f, "%s\n", n->data);
}
}
9b7237ac aquamaniac
else if (n->type==GWEN_XMLNodeTypeComment) {
d8f33628 aquamaniac
fprintf(f, "<!--");
if (n->data) {
fprintf(f, "%s", n->data);
}
fprintf(f, "-->\n");
}
else {
9b7237ac aquamaniac
DBG_ERROR(0, "Unknown tag type (%d)", n->type);
d8f33628 aquamaniac
}
}


9b7237ac aquamaniac
GWEN_XMLNODE *GWEN_XMLNode_FindNode(GWEN_XMLNODE *node,
GWEN_XMLNODE_TYPE t, const char *data) {
GWEN_XMLNODE *n;
d8f33628 aquamaniac
assert(node);
assert(data);

n=node->child;
while(n) {
if (n->type==t)
if (n->data)
if (strcasecmp(n->data, data)==0)
break;
n=n->next;
} /* while */

if (!n) {
9b7237ac aquamaniac
DBG_DEBUG(0, "Node %d:\"%s\" not found", t, data);
d8f33628 aquamaniac
return 0;
}

return n;
}


9b7237ac aquamaniac
void GWEN_XMLNode_UnlinkChild(GWEN_XMLNODE *n, GWEN_XMLNODE *child){
d8f33628 aquamaniac
assert(n);
assert(child);
9b7237ac aquamaniac
GWEN_XMLNode_del(child, &(n->child));
d8f33628 aquamaniac
child->next=0;
child->parent=0;
}



0200e1e7 aquamaniac
void GWEN_XMLNode_RemoveChildren(GWEN_XMLNODE *n){
GWEN_XMLNODE *cn;

assert(n);
cn=n->child;
while(cn) {
GWEN_XMLNODE *ncn;

ncn=cn->next;
GWEN_XMLNode_free(cn);
cn=ncn;
} /* while */
n->child=0;
}