diff options
Diffstat (limited to 'e-util/e-xml-utils.c')
-rw-r--r-- | e-util/e-xml-utils.c | 562 |
1 files changed, 125 insertions, 437 deletions
diff --git a/e-util/e-xml-utils.c b/e-util/e-xml-utils.c index f80d6f0b93..aaa66b6010 100644 --- a/e-util/e-xml-utils.c +++ b/e-util/e-xml-utils.c @@ -1,35 +1,29 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-xml-utils.c - * Copyright 2000, 2001, Ximian, Inc. +/* + * This program 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 of the License, or (at your option) version 3. * - * Authors: - * Chris Lahey <clahey@ximian.com> + * 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 + * Lesser General Public License for more details. * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> * - * 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 - * Library General Public License for more details. * - * You should have received a copy of the GNU Library 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. + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ - #ifdef HAVE_CONFIG_H #include <config.h> #endif -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif - #include "e-xml-utils.h" #include <stdio.h> @@ -42,28 +36,14 @@ #include <fcntl.h> #include <errno.h> #include <math.h> +#include <string.h> -#include <parser.h> -#include <xmlmemory.h> - -#include "gal/util/e-i18n.h" -#include "gal/util/e-util.h" - -xmlNode * -e_xml_get_child_by_name (const xmlNode *parent, const xmlChar *child_name) -{ - xmlNode *child; +#include <glib/gi18n.h> +#include <glib/gstdio.h> +#include <libxml/parser.h> +#include <libxml/xmlmemory.h> - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (child_name != NULL, NULL); - - for (child = parent->xmlChildrenNode; child != NULL; child = child->next) { - if (xmlStrcmp (child->name, child_name) == 0) { - return child; - } - } - return NULL; -} +#include "e-misc-utils.h" /* Returns the first child with the name child_name and the "lang" * attribute that matches the current LC_MESSAGES, or else, the first @@ -71,9 +51,12 @@ e_xml_get_child_by_name (const xmlNode *parent, const xmlChar *child_name) */ xmlNode * e_xml_get_child_by_name_by_lang (const xmlNode *parent, - const xmlChar *child_name, - const gchar *lang) + const xmlChar *child_name, + const gchar *lang) { +#ifdef G_OS_WIN32 + gchar *freeme = NULL; +#endif xmlNode *child; /* This is the default version of the string. */ xmlNode *C = NULL; @@ -82,48 +65,59 @@ e_xml_get_child_by_name_by_lang (const xmlNode *parent, g_return_val_if_fail (child_name != NULL, NULL); if (lang == NULL) { +#ifndef G_OS_WIN32 #ifdef HAVE_LC_MESSAGES lang = setlocale (LC_MESSAGES, NULL); #else lang = setlocale (LC_CTYPE, NULL); #endif +#else + lang = freeme = g_win32_getlocale (); +#endif } for (child = parent->xmlChildrenNode; child != NULL; child = child->next) { if (xmlStrcmp (child->name, child_name) == 0) { - xmlChar *this_lang = xmlGetProp (child, "lang"); + xmlChar *this_lang = xmlGetProp ( + child, (const guchar *)"lang"); if (this_lang == NULL) { C = child; - } else if (xmlStrcmp(this_lang, "lang") == 0) { + } else if (xmlStrcmp (this_lang, (xmlChar *) lang) == 0) { +#ifdef G_OS_WIN32 + g_free (freeme); +#endif return child; } } } +#ifdef G_OS_WIN32 + g_free (freeme); +#endif return C; } static xmlNode * e_xml_get_child_by_name_by_lang_list_with_score (const xmlNode *parent, - const gchar *name, - GList *lang_list, - gint *best_lang_score) + const gchar *name, + const GList *lang_list, + gint *best_lang_score) { xmlNodePtr best_node = NULL, node; for (node = parent->xmlChildrenNode; node != NULL; node = node->next) { xmlChar *lang; - if (node->name == NULL || strcmp (node->name, name) != 0) { + if (node->name == NULL || strcmp ((gchar *) node->name, name) != 0) { continue; } - lang = xmlGetProp (node, "xml:lang"); + lang = xmlGetProp (node, (const guchar *)"xml:lang"); if (lang != NULL) { - GList *l; + const GList *l; gint i; for (l = lang_list, i = 0; l != NULL && i < *best_lang_score; l = l->next, i++) { - if (strcmp ((gchar *) l->data, lang) == 0) { + if (strcmp ((gchar *) l->data, (gchar *) lang) == 0) { best_node = node; *best_lang_score = i; } @@ -136,20 +130,16 @@ e_xml_get_child_by_name_by_lang_list_with_score (const xmlNode *parent, xmlFree (lang); if (*best_lang_score == 0) { return best_node; - } + } } return best_node; } -/* - * e_xml_get_child_by_name_by_lang_list: - * - */ xmlNode * e_xml_get_child_by_name_by_lang_list (const xmlNode *parent, - const gchar *name, - GList *lang_list) + const gchar *name, + const GList *lang_list) { gint best_lang_score = INT_MAX; @@ -157,7 +147,12 @@ e_xml_get_child_by_name_by_lang_list (const xmlNode *parent, g_return_val_if_fail (name != NULL, NULL); if (lang_list == NULL) { - lang_list = gnome_i18n_get_language_list ("LC_MESSAGES"); + const gchar * const *language_names; + + language_names = g_get_language_names (); + while (*language_names != NULL) + lang_list = g_list_append ( + (GList *) lang_list, (gchar *) * language_names++); } return e_xml_get_child_by_name_by_lang_list_with_score (parent,name, @@ -165,12 +160,9 @@ e_xml_get_child_by_name_by_lang_list (const xmlNode *parent, &best_lang_score); } -/* - * e_xml_get_child_by_name_no_lang - * - */ xmlNode * -e_xml_get_child_by_name_no_lang (const xmlNode *parent, const gchar *name) +e_xml_get_child_by_name_no_lang (const xmlNode *parent, + const gchar *name) { xmlNodePtr node; @@ -180,10 +172,10 @@ e_xml_get_child_by_name_no_lang (const xmlNode *parent, const gchar *name) for (node = parent->xmlChildrenNode; node != NULL; node = node->next) { xmlChar *lang; - if (node->name == NULL || strcmp (node->name, name) != 0) { + if (node->name == NULL || strcmp ((gchar *) node->name, name) != 0) { continue; } - lang = xmlGetProp (node, "xml:lang"); + lang = xmlGetProp (node, (const guchar *)"xml:lang"); if (lang == NULL) { return node; } @@ -194,7 +186,8 @@ e_xml_get_child_by_name_no_lang (const xmlNode *parent, const gchar *name) } gint -e_xml_get_integer_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) +e_xml_get_integer_prop_by_name (const xmlNode *parent, + const xmlChar *prop_name) { g_return_val_if_fail (parent != NULL, 0); g_return_val_if_fail (prop_name != NULL, 0); @@ -204,8 +197,8 @@ e_xml_get_integer_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) gint e_xml_get_integer_prop_by_name_with_default (const xmlNode *parent, - const xmlChar *prop_name, - gint def) + const xmlChar *prop_name, + gint def) { xmlChar *prop; gint ret_val = def; @@ -215,7 +208,7 @@ e_xml_get_integer_prop_by_name_with_default (const xmlNode *parent, prop = xmlGetProp ((xmlNode *) parent, prop_name); if (prop != NULL) { - (void) sscanf (prop, "%d", &ret_val); + (void) sscanf ((gchar *) prop, "%d", &ret_val); xmlFree (prop); } return ret_val; @@ -223,8 +216,8 @@ e_xml_get_integer_prop_by_name_with_default (const xmlNode *parent, void e_xml_set_integer_prop_by_name (xmlNode *parent, - const xmlChar *prop_name, - gint value) + const xmlChar *prop_name, + gint value) { gchar *valuestr; @@ -232,12 +225,13 @@ e_xml_set_integer_prop_by_name (xmlNode *parent, g_return_if_fail (prop_name != NULL); valuestr = g_strdup_printf ("%d", value); - xmlSetProp (parent, prop_name, valuestr); + xmlSetProp (parent, prop_name, (guchar *) valuestr); g_free (valuestr); } guint -e_xml_get_uint_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) +e_xml_get_uint_prop_by_name (const xmlNode *parent, + const xmlChar *prop_name) { g_return_val_if_fail (parent != NULL, 0); g_return_val_if_fail (prop_name != NULL, 0); @@ -247,8 +241,8 @@ e_xml_get_uint_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) guint e_xml_get_uint_prop_by_name_with_default (const xmlNode *parent, - const xmlChar *prop_name, - guint def) + const xmlChar *prop_name, + guint def) { xmlChar *prop; guint ret_val = def; @@ -258,7 +252,7 @@ e_xml_get_uint_prop_by_name_with_default (const xmlNode *parent, prop = xmlGetProp ((xmlNode *) parent, prop_name); if (prop != NULL) { - (void) sscanf (prop, "%u", &ret_val); + (void) sscanf ((gchar *) prop, "%u", &ret_val); xmlFree (prop); } return ret_val; @@ -266,8 +260,8 @@ e_xml_get_uint_prop_by_name_with_default (const xmlNode *parent, void e_xml_set_uint_prop_by_name (xmlNode *parent, - const xmlChar *prop_name, - guint value) + const xmlChar *prop_name, + guint value) { gchar *valuestr; @@ -275,26 +269,25 @@ e_xml_set_uint_prop_by_name (xmlNode *parent, g_return_if_fail (prop_name != NULL); valuestr = g_strdup_printf ("%u", value); - xmlSetProp (parent, prop_name, valuestr); + xmlSetProp (parent, prop_name, (guchar *) valuestr); g_free (valuestr); } gboolean e_xml_get_bool_prop_by_name (const xmlNode *parent, - const xmlChar *prop_name) + const xmlChar *prop_name) { g_return_val_if_fail (parent != NULL, 0); g_return_val_if_fail (prop_name != NULL, 0); - return e_xml_get_bool_prop_by_name_with_default (parent, - prop_name, - FALSE); + return e_xml_get_bool_prop_by_name_with_default ( + parent, prop_name, FALSE); } gboolean -e_xml_get_bool_prop_by_name_with_default(const xmlNode *parent, - const xmlChar *prop_name, - gboolean def) +e_xml_get_bool_prop_by_name_with_default (const xmlNode *parent, + const xmlChar *prop_name, + gboolean def) { xmlChar *prop; gboolean ret_val = def; @@ -304,31 +297,34 @@ e_xml_get_bool_prop_by_name_with_default(const xmlNode *parent, prop = xmlGetProp ((xmlNode *) parent, prop_name); if (prop != NULL) { - if (g_strcasecmp (prop, "true") == 0) { + if (g_ascii_strcasecmp ((gchar *) prop, "true") == 0) { ret_val = TRUE; - } else if (g_strcasecmp (prop, "false") == 0) { + } else if (g_ascii_strcasecmp ((gchar *) prop, "false") == 0) { ret_val = FALSE; } - xmlFree(prop); + xmlFree (prop); } return ret_val; } void -e_xml_set_bool_prop_by_name (xmlNode *parent, const xmlChar *prop_name, gboolean value) +e_xml_set_bool_prop_by_name (xmlNode *parent, + const xmlChar *prop_name, + gboolean value) { g_return_if_fail (parent != NULL); g_return_if_fail (prop_name != NULL); if (value) { - xmlSetProp (parent, prop_name, "true"); + xmlSetProp (parent, prop_name, (const guchar *)"true"); } else { - xmlSetProp (parent, prop_name, "false"); + xmlSetProp (parent, prop_name, (const guchar *)"false"); } } gdouble -e_xml_get_double_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) +e_xml_get_double_prop_by_name (const xmlNode *parent, + const xmlChar *prop_name) { g_return_val_if_fail (parent != NULL, 0); g_return_val_if_fail (prop_name != NULL, 0); @@ -337,7 +333,9 @@ e_xml_get_double_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) } gdouble -e_xml_get_double_prop_by_name_with_default (const xmlNode *parent, const xmlChar *prop_name, gdouble def) +e_xml_get_double_prop_by_name_with_default (const xmlNode *parent, + const xmlChar *prop_name, + gdouble def) { xmlChar *prop; gdouble ret_val = def; @@ -347,17 +345,19 @@ e_xml_get_double_prop_by_name_with_default (const xmlNode *parent, const xmlChar prop = xmlGetProp ((xmlNode *) parent, prop_name); if (prop != NULL) { - ret_val = e_flexible_strtod (prop, NULL); + ret_val = e_flexible_strtod ((gchar *) prop, NULL); xmlFree (prop); } return ret_val; } void -e_xml_set_double_prop_by_name(xmlNode *parent, const xmlChar *prop_name, gdouble value) +e_xml_set_double_prop_by_name (xmlNode *parent, + const xmlChar *prop_name, + gdouble value) { - char buffer[E_ASCII_DTOSTR_BUF_SIZE]; - char *format; + gchar buffer[E_ASCII_DTOSTR_BUF_SIZE]; + gchar *format; g_return_if_fail (parent != NULL); g_return_if_fail (prop_name != NULL); @@ -370,30 +370,33 @@ e_xml_set_double_prop_by_name(xmlNode *parent, const xmlChar *prop_name, gdouble e_ascii_dtostr (buffer, sizeof (buffer), format, value); g_free (format); - xmlSetProp (parent, prop_name, buffer); + xmlSetProp (parent, prop_name, (const guchar *) buffer); } gchar * -e_xml_get_string_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) +e_xml_get_string_prop_by_name (const xmlNode *parent, + const xmlChar *prop_name) { - g_return_val_if_fail (parent != NULL, 0); - g_return_val_if_fail (prop_name != NULL, 0); + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (prop_name != NULL, NULL); return e_xml_get_string_prop_by_name_with_default (parent, prop_name, NULL); } gchar * -e_xml_get_string_prop_by_name_with_default (const xmlNode *parent, const xmlChar *prop_name, const gchar *def) +e_xml_get_string_prop_by_name_with_default (const xmlNode *parent, + const xmlChar *prop_name, + const gchar *def) { xmlChar *prop; gchar *ret_val; - g_return_val_if_fail (parent != NULL, 0); - g_return_val_if_fail (prop_name != NULL, 0); + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (prop_name != NULL, NULL); prop = xmlGetProp ((xmlNode *) parent, prop_name); if (prop != NULL) { - ret_val = g_strdup (prop); + ret_val = g_strdup ((gchar *) prop); xmlFree (prop); } else { ret_val = g_strdup (def); @@ -402,359 +405,44 @@ e_xml_get_string_prop_by_name_with_default (const xmlNode *parent, const xmlChar } void -e_xml_set_string_prop_by_name (xmlNode *parent, const xmlChar *prop_name, const gchar *value) +e_xml_set_string_prop_by_name (xmlNode *parent, + const xmlChar *prop_name, + const gchar *value) { g_return_if_fail (parent != NULL); g_return_if_fail (prop_name != NULL); if (value != NULL) { - xmlSetProp (parent, prop_name, value); + xmlSetProp (parent, prop_name, (guchar *) value); } } gchar * -e_xml_get_translated_string_prop_by_name (const xmlNode *parent, const xmlChar *prop_name) +e_xml_get_translated_string_prop_by_name (const xmlNode *parent, + const xmlChar *prop_name) { xmlChar *prop; gchar *ret_val = NULL; gchar *combined_name; - g_return_val_if_fail (parent != NULL, 0); - g_return_val_if_fail (prop_name != NULL, 0); + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (prop_name != NULL, NULL); prop = xmlGetProp ((xmlNode *) parent, prop_name); if (prop != NULL) { - ret_val = g_strdup (prop); + ret_val = g_strdup ((gchar *) prop); xmlFree (prop); return ret_val; } - combined_name = g_strdup_printf("_%s", prop_name); - prop = xmlGetProp ((xmlNode *) parent, combined_name); + combined_name = g_strdup_printf ("_%s", prop_name); + prop = xmlGetProp ((xmlNode *) parent, (guchar *) combined_name); if (prop != NULL) { - ret_val = g_strdup (gettext(prop)); + ret_val = g_strdup (gettext ((gchar *) prop)); xmlFree (prop); } - g_free(combined_name); + g_free (combined_name); return ret_val; } - -/* Replacement for xmlSaveFile */ - -static void xmlNodeDump (xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level, int format); - - -static void -xmlAttrDump (xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) -{ - xmlChar *value; - - if (cur == NULL) { -#ifdef DEBUG_TREE - fprintf(stderr, "xmlAttrDump : property == NULL\n"); -#endif - return; - } - - xmlBufferWriteChar (buf, " "); - if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { - xmlBufferWriteCHAR (buf, cur->ns->prefix); - xmlBufferWriteChar (buf, ":"); - } - - xmlBufferWriteCHAR (buf, cur->name); - value = xmlNodeListGetString (doc, cur->val, 0); - if (value) { - xmlBufferWriteChar (buf, "="); - xmlBufferWriteQuotedString (buf, value); - xmlFree (value); - } else { - xmlBufferWriteChar (buf, "=\"\""); - } -} - -static void -xmlAttrListDump (xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur) -{ - if (cur == NULL) { -#ifdef DEBUG_TREE - fprintf(stderr, "xmlAttrListDump : property == NULL\n"); -#endif - return; - } - - while (cur != NULL) { - xmlAttrDump (buf, doc, cur); - cur = cur->next; - } -} - -static void -xmlNodeListDump (xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level, int format) -{ - int i; - - if (cur == NULL) { -#ifdef DEBUG_TREE - fprintf(stderr, "xmlNodeListDump : node == NULL\n"); -#endif - return; - } - - while (cur != NULL) { - if ((format) && (xmlIndentTreeOutput) && - (cur->type == XML_ELEMENT_NODE)) - for (i = 0; i < level; i++) - xmlBufferWriteChar (buf, " "); - xmlNodeDump (buf, doc, cur, level, format); - if (format) { - xmlBufferWriteChar (buf, "\n"); - } - cur = cur->next; - } -} - -static void -xmlNodeDump (xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level, int format) -{ - int i; - xmlNodePtr tmp; - - if (cur == NULL) { -#ifdef DEBUG_TREE - fprintf(stderr, "xmlNodeDump : node == NULL\n"); -#endif - return; - } - - if (cur->type == XML_TEXT_NODE) { - if (cur->content != NULL) { - xmlChar *buffer; - -#ifndef XML_USE_BUFFER_CONTENT - buffer = xmlEncodeEntitiesReentrant (doc, cur->content); -#else - buffer = xmlEncodeEntitiesReentrant (doc, xmlBufferContent (cur->content)); -#endif - if (buffer != NULL) { - xmlBufferWriteCHAR (buf, buffer); - xmlFree (buffer); - } - } - return; - } - - if (cur->type == XML_PI_NODE) { - if (cur->content != NULL) { - xmlBufferWriteChar (buf, "<?"); - xmlBufferWriteCHAR (buf, cur->name); - if (cur->content != NULL) { - xmlBufferWriteChar (buf, " "); -#ifndef XML_USE_BUFFER_CONTENT - xmlBufferWriteCHAR (buf, cur->content); -#else - xmlBufferWriteCHAR (buf, xmlBufferContent (cur->content)); -#endif - } - xmlBufferWriteChar (buf, "?>"); - } - return; - } - - if (cur->type == XML_COMMENT_NODE) { - if (cur->content != NULL) { - xmlBufferWriteChar (buf, "<!--"); -#ifndef XML_USE_BUFFER_CONTENT - xmlBufferWriteCHAR (buf, cur->content); -#else - xmlBufferWriteCHAR (buf, xmlBufferContent (cur->content)); -#endif - xmlBufferWriteChar (buf, "-->"); - } - return; - } - - if (cur->type == XML_ENTITY_REF_NODE) { - xmlBufferWriteChar (buf, "&"); - xmlBufferWriteCHAR (buf, cur->name); - xmlBufferWriteChar (buf, ";"); - return; - } - - if (cur->type == XML_CDATA_SECTION_NODE) { - xmlBufferWriteChar (buf, "<![CDATA["); - if (cur->content != NULL) -#ifndef XML_USE_BUFFER_CONTENT - xmlBufferWriteCHAR (buf, cur->content); -#else - xmlBufferWriteCHAR (buf, xmlBufferContent(cur->content)); -#endif - xmlBufferWriteChar (buf, "]]>"); - return; - } - - if (format == 1) { - tmp = cur->childs; - while (tmp != NULL) { - if ((tmp->type == XML_TEXT_NODE) || - (tmp->type == XML_ENTITY_REF_NODE)) { - format = 0; - break; - } - tmp = tmp->next; - } - } - - xmlBufferWriteChar (buf, "<"); - if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { - xmlBufferWriteCHAR (buf, cur->ns->prefix); - xmlBufferWriteChar (buf, ":"); - } - - xmlBufferWriteCHAR (buf, cur->name); - - if (cur->properties != NULL) - xmlAttrListDump (buf, doc, cur->properties); - - if ((cur->content == NULL) && (cur->childs == NULL) && - (!xmlSaveNoEmptyTags)) { - xmlBufferWriteChar (buf, "/>"); - return; - } - - xmlBufferWriteChar (buf, ">"); - if (cur->content != NULL) { - xmlChar *buffer; - -#ifndef XML_USE_BUFFER_CONTENT - buffer = xmlEncodeEntitiesReentrant (doc, cur->content); -#else - buffer = xmlEncodeEntitiesReentrant (doc, xmlBufferContent (cur->content)); -#endif - if (buffer != NULL) { - xmlBufferWriteCHAR (buf, buffer); - xmlFree (buffer); - } - } - - if (cur->childs != NULL) { - if (format) - xmlBufferWriteChar (buf, "\n"); - - xmlNodeListDump (buf, doc, cur->childs, (level >= 0 ? level + 1 : -1), format); - if ((xmlIndentTreeOutput) && (format)) - for (i = 0; i < level; i++) - xmlBufferWriteChar (buf, " "); - } - - xmlBufferWriteChar (buf, "</"); - if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { - xmlBufferWriteCHAR (buf, cur->ns->prefix); - xmlBufferWriteChar (buf, ":"); - } - - xmlBufferWriteCHAR (buf, cur->name); - xmlBufferWriteChar (buf, ">"); -} - -static void -xmlDocContentDump (xmlBufferPtr buf, xmlDocPtr cur) -{ - xmlBufferWriteChar (buf, "<?xml version="); - - if (cur->version != NULL) - xmlBufferWriteQuotedString (buf, cur->version); - else - xmlBufferWriteChar (buf, "\"1.0\""); - - if ((cur->encoding != NULL) && - (strcasecmp (cur->encoding, "UTF-8") != 0)) { - xmlBufferWriteChar (buf, " encoding="); - xmlBufferWriteQuotedString (buf, cur->encoding); - } - - switch (cur->standalone) { - case 1: - xmlBufferWriteChar (buf, " standalone=\"yes\""); - break; - } - - xmlBufferWriteChar (buf, "?>\n"); - if (cur->root != NULL) { - xmlNodePtr child = cur->root; - - while (child != NULL) { - xmlNodeDump (buf, cur, child, 0, 1); - xmlBufferWriteChar (buf, "\n"); - child = child->next; - } - } -} - -int -e_xml_save_file (const char *filename, xmlDocPtr doc) -{ - char *filesave, *slash; - size_t n, written = 0; - xmlBufferPtr buf; - int errnosave; - int ret, fd; - ssize_t w; - - filesave = alloca (strlen (filename) + 5); - slash = strrchr (filename, '/'); - if (slash) - sprintf (filesave, "%.*s.#%s", slash - filename + 1, filename, slash + 1); - else - sprintf (filesave, ".#%s", filename); - - fd = open (filesave, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd == -1) - return -1; - - if (!(buf = xmlBufferCreate ())) { - close (fd); - unlink (filesave); - errno = ENOMEM; - return -1; - } - - xmlDocContentDump (buf, doc); - - n = buf->use; - do { - do { - w = write (fd, buf->content + written, n - written); - } while (w == -1 && errno == EINTR); - - if (w > 0) - written += w; - } while (w != -1 && written < n); - - xmlBufferFree (buf); - - if (written < n || fsync (fd) == -1) { - errnosave = errno; - close (fd); - unlink (filesave); - errno = errnosave; - return -1; - } - - while ((ret = close (fd)) == -1 && errno == EINTR) - ; - - if (ret == -1) - return -1; - - if (rename (filesave, filename) == -1) { - errnosave = errno; - unlink (filesave); - errno = errnosave; - return -1; - } - - return 0; -} |