X-Git-Url: http://git.onelab.eu/?p=plcapi.git;a=blobdiff_plain;f=php%2Fxmlrpc%2Flibxmlrpc%2Fxml_element.c;fp=php%2Fxmlrpc%2Flibxmlrpc%2Fxml_element.c;h=0000000000000000000000000000000000000000;hp=ae30838f5d3e8e01b1228f907a3e3ce0e7d227c8;hb=e48b0945a0f03a51019f72399ac9f0eeabb90211;hpb=f9ac2727e6fbddf97e885ffa1271a562315fb274 diff --git a/php/xmlrpc/libxmlrpc/xml_element.c b/php/xmlrpc/libxmlrpc/xml_element.c deleted file mode 100644 index ae30838..0000000 --- a/php/xmlrpc/libxmlrpc/xml_element.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - This file is part of libXMLRPC - a C library for xml-encoded function calls. - - Author: Dan Libby (dan@libby.com) - Epinions.com may be contacted at feedback@epinions-inc.com -*/ - -/* - Copyright 2000 Epinions, Inc. - - Subject to the following 3 conditions, Epinions, Inc. permits you, free - of charge, to (a) use, copy, distribute, modify, perform and display this - software and associated documentation files (the "Software"), and (b) - permit others to whom the Software is furnished to do so as well. - - 1) The above copyright notice and this permission notice shall be included - without modification in all copies or substantial portions of the - Software. - - 2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF - ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY - IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE OR NONINFRINGEMENT. - - 3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, - SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT - OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING - NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH - DAMAGES. - -*/ - - -static const char rcsid[] = "#(@) $Id$"; - - - -/****h* ABOUT/xml_element - * NAME - * xml_element - * AUTHOR - * Dan Libby, aka danda (dan@libby.com) - * CREATION DATE - * 06/2000 - * HISTORY - * $Log: xml_element.c,v $ - * Revision 1.6 2004/06/01 20:16:06 iliaa - * Fixed bug #28597 (xmlrpc_encode_request() incorrectly encodes chars in - * 200-210 range). - * Patch by: fernando dot nemec at folha dot com dot br - * - * Revision 1.5 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * - * Revision 1.4 2002/11/26 23:01:16 fmk - * removing unused variables - * - * Revision 1.3 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * - * Revision 1.9 2002/07/03 20:54:30 danda - * root element should not have a parent. patch from anon SF user - * - * Revision 1.8 2002/05/23 17:46:51 danda - * patch from mukund - fix non utf-8 encoding conversions - * - * Revision 1.7 2002/02/13 20:58:50 danda - * patch to make source more windows friendly, contributed by Jeff Lawson - * - * Revision 1.6 2002/01/08 01:06:55 danda - * enable format for parsers that are very picky. - * - * Revision 1.5 2001/09/29 21:58:05 danda - * adding cvs log to history section - * - * 10/15/2000 -- danda -- adding robodoc documentation - * TODO - * Nicer external API. Get rid of macros. Make opaque types, etc. - * PORTABILITY - * Coded on RedHat Linux 6.2. Builds on Solaris x86. Should build on just - * about anything with minor mods. - * NOTES - * This code incorporates ideas from expat-ensor from http://xml.ensor.org. - * - * It was coded primarily to act as a go-between for expat and xmlrpc. To this - * end, it stores xml elements, their sub-elements, and their attributes in an - * in-memory tree. When expat is done parsing, the tree can be walked, thus - * retrieving the values. The code can also be used to build a tree via API then - * write out the tree to a buffer, thus "serializing" the xml. - * - * It turns out this is useful for other purposes, such as parsing config files. - * YMMV. - * - * Some Features: - * - output option for xml escaping data. Choices include no escaping, entity escaping, - * or CDATA sections. - * - output option for character encoding. Defaults to (none) utf-8. - * - output option for verbosity/readability. ultra-compact, newlines, pretty/level indented. - * - * BUGS - * there must be some. - ******/ - -#ifdef _WIN32 -#include "xmlrpc_win32.h" -#endif -#include -#include -#include - -#include "xml_element.h" -#include "queue.h" -#include "expat.h" -#include "encodings.h" - -#define my_free(thing) if(thing) {free(thing); thing = NULL;} - -#define XML_DECL_START "" -#define XML_DECL_END_LEN sizeof(XML_DECL_END) - 1 -#define START_TOKEN_BEGIN "<" -#define START_TOKEN_BEGIN_LEN sizeof(START_TOKEN_BEGIN) - 1 -#define START_TOKEN_END ">" -#define START_TOKEN_END_LEN sizeof(START_TOKEN_END) - 1 -#define EMPTY_START_TOKEN_END "/>" -#define EMPTY_START_TOKEN_END_LEN sizeof(EMPTY_START_TOKEN_END) - 1 -#define END_TOKEN_BEGIN "" -#define END_TOKEN_END_LEN sizeof(END_TOKEN_END) - 1 -#define ATTR_DELIMITER "\"" -#define ATTR_DELIMITER_LEN sizeof(ATTR_DELIMITER) - 1 -#define CDATA_BEGIN "" -#define CDATA_END_LEN sizeof(CDATA_END) - 1 -#define EQUALS "=" -#define EQUALS_LEN sizeof(EQUALS) - 1 -#define WHITESPACE " " -#define WHITESPACE_LEN sizeof(WHITESPACE) - 1 -#define NEWLINE "\n" -#define NEWLINE_LEN sizeof(NEWLINE) - 1 -#define MAX_VAL_BUF 144 -#define SCALAR_STR "SCALAR" -#define SCALAR_STR_LEN sizeof(SCALAR_STR) - 1 -#define VECTOR_STR "VECTOR" -#define VECTOR_STR_LEN sizeof(VECTOR_STR) - 1 -#define RESPONSE_STR "RESPONSE" -#define RESPONSE_STR_LEN sizeof(RESPONSE_STR) - 1 - - -/*----------------------------- -- Begin xml_element Functions - ------------------------------*/ - -/****f* xml_element/xml_elem_free_non_recurse - * NAME - * xml_elem_free_non_recurse - * SYNOPSIS - * void xml_elem_free_non_recurse(xml_element* root) - * FUNCTION - * free a single xml element. child elements will not be freed. - * INPUTS - * root - the element to free - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_free () - * xml_elem_new () - * SOURCE - */ -void xml_elem_free_non_recurse(xml_element* root) { - if(root) { - xml_element_attr* attrs = Q_Head(&root->attrs); - while(attrs) { - my_free(attrs->key); - my_free(attrs->val); - my_free(attrs); - attrs = Q_Next(&root->attrs); - } - - Q_Destroy(&root->children); - Q_Destroy(&root->attrs); - if (root->name) { - free((char *)root->name); - root->name = NULL; - } - simplestring_free(&root->text); - my_free(root); - } -} -/******/ - -/****f* xml_element/xml_elem_free - * NAME - * xml_elem_free - * SYNOPSIS - * void xml_elem_free(xml_element* root) - * FUNCTION - * free an xml element and all of its child elements - * INPUTS - * root - the root of an xml tree you would like to free - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_free_non_recurse () - * xml_elem_new () - * SOURCE - */ -void xml_elem_free(xml_element* root) { - if(root) { - xml_element* kids = Q_Head(&root->children); - while(kids) { - xml_elem_free(kids); - kids = Q_Next(&root->children); - } - xml_elem_free_non_recurse(root); - } -} -/******/ - -/****f* xml_element/xml_elem_new - * NAME - * xml_elem_new - * SYNOPSIS - * xml_element* xml_elem_new() - * FUNCTION - * allocates and initializes a new xml_element - * INPUTS - * none - * RESULT - * xml_element* or NULL. NULL indicates an out-of-memory condition. - * NOTES - * SEE ALSO - * xml_elem_free () - * xml_elem_free_non_recurse () - * SOURCE - */ -xml_element* xml_elem_new() { - xml_element* elem = calloc(1, sizeof(xml_element)); - if(elem) { - Q_Init(&elem->children); - Q_Init(&elem->attrs); - simplestring_init(&elem->text); - - /* init empty string in case we don't find any char data */ - simplestring_addn(&elem->text, "", 0); - } - return elem; -} -/******/ - -static int xml_elem_writefunc(int (*fptr)(void *data, const char *text, int size), const char *text, void *data, int len) -{ - return fptr && text ? fptr(data, text, len ? len : strlen(text)) : 0; -} - - - -static int create_xml_escape(char *pString, unsigned char c) -{ - int counter = 0; - - pString[counter++] = '&'; - pString[counter++] = '#'; - if(c >= 100) { - pString[counter++] = c / 100 + '0'; - c = c % 100; - } - pString[counter++] = c / 10 + '0'; - c = c % 10; - - pString[counter++] = c + '0'; - pString[counter++] = ';'; - return counter; -} - -#define non_ascii(c) (c > 127) -#define non_print(c) (!isprint(c)) -#define markup(c) (c == '&' || c == '\"' || c == '>' || c == '<') -#define entity_length(c) ( (c >= 100) ? 3 : ((c >= 10) ? 2 : 1) ) + 3; /* "&#" + c + ";" */ - -/* - * xml_elem_entity_escape - * - * Purpose: - * escape reserved xml chars and non utf-8 chars as xml entities - * Comments: - * The return value may be a new string, or null if no - * conversion was performed. In the latter case, *newlen will - * be 0. - * Flags (to escape) - * xml_elem_no_escaping = 0x000, - * xml_elem_entity_escaping = 0x002, // escape xml special chars as entities - * xml_elem_non_ascii_escaping = 0x008, // escape chars above 127 - * xml_elem_cdata_escaping = 0x010, // wrap in cdata - */ -static char* xml_elem_entity_escape(const char* buf, int old_len, int *newlen, XML_ELEM_ESCAPING flags) { - char *pRetval = 0; - int iNewBufLen=0; - -#define should_escape(c, flag) ( ((flag & xml_elem_markup_escaping) && markup(c)) || \ - ((flag & xml_elem_non_ascii_escaping) && non_ascii(c)) || \ - ((flag & xml_elem_non_print_escaping) && non_print(c)) ) - - if(buf && *buf) { - const unsigned char *bufcopy; - char *NewBuffer; - int ToBeXmlEscaped=0; - int iLength; - bufcopy = buf; - iLength= old_len ? old_len : strlen(buf); - while(*bufcopy) { - if( should_escape(*bufcopy, flags) ) { - /* the length will increase by length of xml escape - the character length */ - iLength += entity_length(*bufcopy); - ToBeXmlEscaped=1; - } - bufcopy++; - } - - if(ToBeXmlEscaped) { - - NewBuffer= malloc(iLength+1); - if(NewBuffer) { - bufcopy=buf; - while(*bufcopy) { - if(should_escape(*bufcopy, flags)) { - iNewBufLen += create_xml_escape(NewBuffer+iNewBufLen,*bufcopy); - } - else { - NewBuffer[iNewBufLen++]=*bufcopy; - } - bufcopy++; - } - NewBuffer[iNewBufLen] = 0; - pRetval = NewBuffer; - } - } - } - - if(newlen) { - *newlen = iNewBufLen; - } - - return pRetval; -} - - -static void xml_element_serialize(xml_element *el, int (*fptr)(void *data, const char *text, int size), void *data, XML_ELEM_OUTPUT_OPTIONS options, int depth) -{ - int i; - static STRUCT_XML_ELEM_OUTPUT_OPTIONS default_opts = {xml_elem_pretty, xml_elem_markup_escaping | xml_elem_non_print_escaping, XML_DECL_ENCODING_DEFAULT}; - static char whitespace[] = " " - " " - " "; - depth++; - - if(!el) { - fprintf(stderr, "Nothing to write\n"); - return; - } - if(!options) { - options = &default_opts; - } - - /* print xml declaration if at root level */ - if(depth == 1) { - xml_elem_writefunc(fptr, XML_DECL_START, data, XML_DECL_START_LEN); - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, XML_DECL_VERSION, data, XML_DECL_VERSION_LEN); - if(options->encoding && *options->encoding) { - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, XML_DECL_ENCODING_ATTR, data, XML_DECL_ENCODING_ATTR_LEN); - xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - xml_elem_writefunc(fptr, options->encoding, data, 0); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - } - xml_elem_writefunc(fptr, XML_DECL_END, data, XML_DECL_END_LEN); - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } - } - - if(options->verbosity == xml_elem_pretty && depth > 2) { - xml_elem_writefunc(fptr, whitespace, data, depth - 2); - } - /* begin element */ - xml_elem_writefunc(fptr,START_TOKEN_BEGIN, data, START_TOKEN_BEGIN_LEN); - if(el->name) { - xml_elem_writefunc(fptr, el->name, data, 0); - - /* write attrs, if any */ - if(Q_Size(&el->attrs)) { - xml_element_attr* iter = Q_Head(&el->attrs); - while( iter ) { - xml_elem_writefunc(fptr, WHITESPACE, data, WHITESPACE_LEN); - xml_elem_writefunc(fptr, iter->key, data, 0); - xml_elem_writefunc(fptr, EQUALS, data, EQUALS_LEN); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - xml_elem_writefunc(fptr, iter->val, data, 0); - xml_elem_writefunc(fptr, ATTR_DELIMITER, data, ATTR_DELIMITER_LEN); - - iter = Q_Next(&el->attrs); - } - } - } - else { - xml_elem_writefunc(fptr, "None", data, 0); - } - /* if no text and no children, use abbreviated form, eg: */ - if(!el->text.len && !Q_Size(&el->children)) { - xml_elem_writefunc(fptr, EMPTY_START_TOKEN_END, data, EMPTY_START_TOKEN_END_LEN); - } - /* otherwise, print element contents */ - else { - xml_elem_writefunc(fptr, START_TOKEN_END, data, START_TOKEN_END_LEN); - - /* print text, if any */ - if(el->text.len) { - char* escaped_str = el->text.str; - int buflen = el->text.len; - - if(options->escaping && options->escaping != xml_elem_cdata_escaping) { - escaped_str = xml_elem_entity_escape(el->text.str, buflen, &buflen, options->escaping ); - if(!escaped_str) { - escaped_str = el->text.str; - } - } - - if(options->escaping & xml_elem_cdata_escaping) { - xml_elem_writefunc(fptr, CDATA_BEGIN, data, CDATA_BEGIN_LEN); - } - - xml_elem_writefunc(fptr, escaped_str, data, buflen); - - if(escaped_str != el->text.str) { - my_free(escaped_str); - } - - if(options->escaping & xml_elem_cdata_escaping) { - xml_elem_writefunc(fptr, CDATA_END, data, CDATA_END_LEN); - } - } - /* no text, so print child elems */ - else { - xml_element *kids = Q_Head(&el->children); - i = 0; - while( kids ) { - if(i++ == 0) { - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } - } - xml_element_serialize(kids, fptr, data, options, depth); - kids = Q_Next(&el->children); - } - if(i) { - if(options->verbosity == xml_elem_pretty && depth > 2) { - xml_elem_writefunc(fptr, whitespace, data, depth - 2); - } - } - } - - xml_elem_writefunc(fptr, END_TOKEN_BEGIN, data, END_TOKEN_BEGIN_LEN); - xml_elem_writefunc(fptr,el->name ? el->name : "None", data, 0); - xml_elem_writefunc(fptr, END_TOKEN_END, data, END_TOKEN_END_LEN); - } - if(options->verbosity != xml_elem_no_white_space) { - xml_elem_writefunc(fptr, NEWLINE, data, NEWLINE_LEN); - } -} - -/* print buf to file */ -static int file_out_fptr(void *f, const char *text, int size) -{ - fputs(text, (FILE *)f); - return 0; -} - -/* print buf to simplestring */ -static int simplestring_out_fptr(void *f, const char *text, int size) -{ - simplestring* buf = (simplestring*)f; - if(buf) { - simplestring_addn(buf, text, size); - } - return 0; -} - -/****f* xml_element/xml_elem_serialize_to_string - * NAME - * xml_elem_serialize_to_string - * SYNOPSIS - * void xml_element_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len) - * FUNCTION - * writes element tree as XML into a newly allocated buffer - * INPUTS - * el - root element of tree - * options - options determining how output is written. see XML_ELEM_OUTPUT_OPTIONS - * buf_len - length of returned buffer, if not null. - * RESULT - * char* or NULL. Must be free'd by caller. - * NOTES - * SEE ALSO - * xml_elem_serialize_to_stream () - * xml_elem_parse_buf () - * SOURCE - */ -char* xml_elem_serialize_to_string(xml_element *el, XML_ELEM_OUTPUT_OPTIONS options, int *buf_len) -{ - simplestring buf; - simplestring_init(&buf); - - xml_element_serialize(el, simplestring_out_fptr, (void *)&buf, options, 0); - - if(buf_len) { - *buf_len = buf.len; - } - - return buf.str; -} -/******/ - -/****f* xml_element/xml_elem_serialize_to_stream - * NAME - * xml_elem_serialize_to_stream - * SYNOPSIS - * void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options) - * FUNCTION - * writes element tree as XML into a stream (typically an opened file) - * INPUTS - * el - root element of tree - * output - stream handle - * options - options determining how output is written. see XML_ELEM_OUTPUT_OPTIONS - * RESULT - * void - * NOTES - * SEE ALSO - * xml_elem_serialize_to_string () - * xml_elem_parse_buf () - * SOURCE - */ -void xml_elem_serialize_to_stream(xml_element *el, FILE *output, XML_ELEM_OUTPUT_OPTIONS options) -{ - xml_element_serialize(el, file_out_fptr, (void *)output, options, 0); -} -/******/ - -/*--------------------------* -* End xml_element Functions * -*--------------------------*/ - - -/*---------------------- -* Begin Expat Handlers * -*---------------------*/ - -typedef struct _xml_elem_data { - xml_element* root; - xml_element* current; - XML_ELEM_INPUT_OPTIONS input_options; - int needs_enc_conversion; -} xml_elem_data; - - -/* expat start of element handler */ -static void startElement(void *userData, const char *name, const char **attrs) -{ - xml_element *c; - xml_elem_data* mydata = (xml_elem_data*)userData; - const char** p = attrs; - - if(mydata) { - c = mydata->current; - - mydata->current = xml_elem_new(); - mydata->current->name = (char*)strdup(name); - mydata->current->parent = c; - - /* init attrs */ - while(p && *p) { - xml_element_attr* attr = malloc(sizeof(xml_element_attr)); - if(attr) { - attr->key = strdup(*p); - attr->val = strdup(*(p+1)); - Q_PushTail(&mydata->current->attrs, attr); - - p += 2; - } - } - } -} - -/* expat end of element handler */ -static void endElement(void *userData, const char *name) -{ - xml_elem_data* mydata = (xml_elem_data*)userData; - - if(mydata && mydata->current && mydata->current->parent) { - Q_PushTail(&mydata->current->parent->children, mydata->current); - - mydata->current = mydata->current->parent; - } -} - -/* expat char data handler */ -static void charHandler(void *userData, - const char *s, - int len) -{ - xml_elem_data* mydata = (xml_elem_data*)userData; - if(mydata && mydata->current) { - - /* Check if we need to decode utf-8 parser output to another encoding */ - if(mydata->needs_enc_conversion && mydata->input_options->encoding) { - int new_len = 0; - char* add_text = utf8_decode(s, len, &new_len, mydata->input_options->encoding); - if(add_text) { - len = new_len; - simplestring_addn(&mydata->current->text, add_text, len); - free(add_text); - return; - } - } - simplestring_addn(&mydata->current->text, s, len); - } -} -/******/ - -/*-------------------* -* End Expat Handlers * -*-------------------*/ - -/*-------------------* -* xml_elem_parse_buf * -*-------------------*/ - -/****f* xml_element/xml_elem_parse_buf - * NAME - * xml_elem_parse_buf - * SYNOPSIS - * xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error) - * FUNCTION - * parse a buffer containing XML into an xml_element in-memory tree - * INPUTS - * in_buf - buffer containing XML document - * len - length of buffer - * options - input options. optional - * error - error result data. optional. check if result is null. - * RESULT - * void - * NOTES - * The returned data must be free'd by caller - * SEE ALSO - * xml_elem_serialize_to_string () - * xml_elem_free () - * SOURCE - */ -xml_element* xml_elem_parse_buf(const char* in_buf, int len, XML_ELEM_INPUT_OPTIONS options, XML_ELEM_ERROR error) -{ - xml_element* xReturn = NULL; - char buf[100] = ""; - static STRUCT_XML_ELEM_INPUT_OPTIONS default_opts = {encoding_utf_8}; - - if(!options) { - options = &default_opts; - } - - if(in_buf) { - XML_Parser parser; - xml_elem_data mydata = {0}; - - parser = XML_ParserCreate(NULL); - - mydata.root = xml_elem_new(); - mydata.current = mydata.root; - mydata.input_options = options; - mydata.needs_enc_conversion = options->encoding && strcmp(options->encoding, encoding_utf_8); - - XML_SetElementHandler(parser, startElement, endElement); - XML_SetCharacterDataHandler(parser, charHandler); - - /* pass the xml_elem_data struct along */ - XML_SetUserData(parser, (void*)&mydata); - - if(!len) { - len = strlen(in_buf); - } - - /* parse the XML */ - if(XML_Parse(parser, in_buf, len, 1) == 0) { - enum XML_Error err_code = XML_GetErrorCode(parser); - int line_num = XML_GetCurrentLineNumber(parser); - int col_num = XML_GetCurrentColumnNumber(parser); - long byte_idx = XML_GetCurrentByteIndex(parser); - int byte_total = XML_GetCurrentByteCount(parser); - const char * error_str = XML_ErrorString(err_code); - if(byte_idx >= 0) { - snprintf(buf, - sizeof(buf), - "\n\tdata beginning %ld before byte index: %s\n", - byte_idx > 10 ? 10 : byte_idx, - in_buf + (byte_idx > 10 ? byte_idx - 10 : byte_idx)); - } - - fprintf(stderr, "expat reports error code %i\n" - "\tdescription: %s\n" - "\tline: %i\n" - "\tcolumn: %i\n" - "\tbyte index: %ld\n" - "\ttotal bytes: %i\n%s ", - err_code, error_str, line_num, - col_num, byte_idx, byte_total, buf); - - - /* error condition */ - if(error) { - error->parser_code = (long)err_code; - error->line = line_num; - error->column = col_num; - error->byte_index = byte_idx; - error->parser_error = error_str; - } - } - else { - xReturn = (xml_element*)Q_Head(&mydata.root->children); - xReturn->parent = NULL; - } - - XML_ParserFree(parser); - - - xml_elem_free_non_recurse(mydata.root); - } - - return xReturn; -} - -/******/