/***** * * Copyright (C) 2004, 2005 Pablo Belin * All Rights Reserved * * This file is part of the gprelude program. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * *****/ #include #include #include #include "gprelude-mem.h" #include "gprelude-xml.h" struct gprelude_xml { gprelude_xml_type_t type; const char *ns; const char *ns_url; unsigned int indent; FILE *fp; }; gprelude_xml_t *gprelude_xml_new ( gprelude_xml_t *xml_parent, FILE *fp ) { gprelude_xml_t *xml; if ( !xml_parent && !fp ) return NULL; xml = malloc ( sizeof(gprelude_xml_t) ); if ( !xml ) return NULL; xml->type = gprelude_xml_type_unknown; xml->ns = NULL; xml->ns_url = NULL; if ( !xml_parent ) { xml->fp = fp; xml->indent = 0; } else { xml->fp = xml_parent->fp; xml->indent = xml_parent->indent; } return xml; } int gprelude_xml_destroy ( gprelude_xml_t *xml ) { return gprelude_free ( xml ); } int gprelude_xml_set_ns ( gprelude_xml_t *xml, const char *ns, const char *ns_url ) { if ( !xml ) return -1; xml->ns = ns; xml->ns_url = ns_url; return 0; } FILE *gprelude_xml_get_fp ( gprelude_xml_t *xml ) { return xml ? xml->fp : NULL; } static void xml_do_indent ( gprelude_xml_t *xml ) { int i; for ( i = 0; i < xml->indent; i++ ) putc ( '\t', xml->fp ); } int gprelude_xml_startDocument ( FILE *fp, const char *version, const char *encoding, int standalone ) { if ( !fp ) return -1; fprintf ( fp, "\n\n", fp ); return 0; } int gprelude_xml_endDocument ( void ) { /* NOP */ return 0; } int gprelude_xml_startElement ( gprelude_xml_t *xml, gprelude_xml_type_t type, const char *fullname, ... ) { va_list ap; char *arg1, *arg2; if ( !xml ) return -1; xml_do_indent ( xml ); if ( xml->ns ) fprintf ( xml->fp, "<%s:", xml->ns ); else putc ( '<', xml->fp ); fprintf ( xml->fp, "%s", fullname ); if ( type&gprelude_xml_type_ns && xml->ns && xml->ns_url ) fprintf ( xml->fp, " xmlns:%s=\"%s\"", xml->ns, xml->ns_url ); va_start ( ap, fullname ); while ( 1 ) { arg1 = va_arg ( ap, char * ); if ( !arg1 ) break; arg2 = va_arg ( ap, char * ); if ( !arg2 ) break; fprintf ( xml->fp, " %s=\"%s\"", arg1, arg2 ); } va_end ( ap ); if ( type&gprelude_xml_type_attributes ) fputs ( "/>\n", xml->fp ); else if ( type&gprelude_xml_type_simple ) fputc ( '>', xml->fp ); else { fputs ( ">\n", xml->fp ); xml->indent ++; } xml->type = type; return 0; } int gprelude_xml_endElement ( gprelude_xml_t *xml, const char *fullname ) { if ( !xml ) return -1; if ( !(xml->type&gprelude_xml_type_simple) ) { if ( xml->indent > 0 ) xml->indent --; xml_do_indent ( xml ); } if ( xml->ns ) fprintf ( xml->fp, "ns ); else fputs ( "fp ); fprintf ( xml->fp, "%s>\n", fullname ); xml->type = gprelude_xml_type_unknown; return 0; } int gprelude_xml_characters ( gprelude_xml_t *xml, const char *str ) { if ( !xml ) return -1; fputs ( str, xml->fp ); return 0; } int gprelude_xml_comment ( gprelude_xml_t *xml, const char *str ) { if ( !xml ) return -1; fprintf ( xml->fp, "", str ); return 0; }