evolution-3.6.4/libevolution-utils/e-xml-utils.c

No issues found

  1 /*
  2  * This program is free software; you can redistribute it and/or
  3  * modify it under the terms of the GNU Lesser General Public
  4  * License as published by the Free Software Foundation; either
  5  * version 2 of the License, or (at your option) version 3.
  6  *
  7  * This program is distributed in the hope that it will be useful,
  8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 10  * Lesser General Public License for more details.
 11  *
 12  * You should have received a copy of the GNU Lesser General Public
 13  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 14  *
 15  *
 16  * Authors:
 17  *		Chris Lahey <clahey@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #ifdef HAVE_CONFIG_H
 24 #include <config.h>
 25 #endif
 26 
 27 #include <stdio.h>
 28 #include <stdlib.h>
 29 #include <string.h>
 30 #include <sys/types.h>
 31 #include <sys/stat.h>
 32 #include <locale.h>
 33 #include <unistd.h>
 34 #include <fcntl.h>
 35 #include <errno.h>
 36 #include <math.h>
 37 #include <string.h>
 38 
 39 #include <glib/gi18n.h>
 40 #include <glib/gstdio.h>
 41 #include <libxml/parser.h>
 42 #include <libxml/xmlmemory.h>
 43 
 44 #include "evolution-util.h"
 45 #include "e-xml-utils.h"
 46 
 47 /* Returns the first child with the name child_name and the "lang"
 48  * attribute that matches the current LC_MESSAGES, or else, the first
 49  * child with the name child_name and no "lang" attribute.
 50  */
 51 xmlNode *
 52 e_xml_get_child_by_name_by_lang (const xmlNode *parent,
 53                                  const xmlChar *child_name,
 54                                  const gchar *lang)
 55 {
 56 #ifdef G_OS_WIN32
 57 	gchar *freeme = NULL;
 58 #endif
 59 	xmlNode *child;
 60 	/* This is the default version of the string. */
 61 	xmlNode *C = NULL;
 62 
 63 	g_return_val_if_fail (parent != NULL, NULL);
 64 	g_return_val_if_fail (child_name != NULL, NULL);
 65 
 66 	if (lang == NULL) {
 67 #ifndef G_OS_WIN32
 68 #ifdef HAVE_LC_MESSAGES
 69 		lang = setlocale (LC_MESSAGES, NULL);
 70 #else
 71 		lang = setlocale (LC_CTYPE, NULL);
 72 #endif
 73 #else
 74 		lang = freeme = g_win32_getlocale ();
 75 #endif
 76 	}
 77 	for (child = parent->xmlChildrenNode; child != NULL; child = child->next) {
 78 		if (xmlStrcmp (child->name, child_name) == 0) {
 79 			xmlChar *this_lang = xmlGetProp (
 80 				child, (const guchar *)"lang");
 81 			if (this_lang == NULL) {
 82 				C = child;
 83 			} else if (xmlStrcmp (this_lang, (xmlChar *) lang) == 0) {
 84 #ifdef G_OS_WIN32
 85 				g_free (freeme);
 86 #endif
 87 				return child;
 88 			}
 89 		}
 90 	}
 91 #ifdef G_OS_WIN32
 92 	g_free (freeme);
 93 #endif
 94 	return C;
 95 }
 96 
 97 static xmlNode *
 98 e_xml_get_child_by_name_by_lang_list_with_score (const xmlNode *parent,
 99                                                  const gchar *name,
100                                                  const GList *lang_list,
101                                                  gint *best_lang_score)
102 {
103 	xmlNodePtr best_node = NULL, node;
104 
105 	for (node = parent->xmlChildrenNode; node != NULL; node = node->next) {
106 		xmlChar *lang;
107 
108 		if (node->name == NULL || strcmp ((gchar *) node->name, name) != 0) {
109 			continue;
110 		}
111 		lang = xmlGetProp (node, (const guchar *)"xml:lang");
112 		if (lang != NULL) {
113 			const GList *l;
114 			gint i;
115 
116 			for (l = lang_list, i = 0;
117 			     l != NULL && i < *best_lang_score;
118 			     l = l->next, i++) {
119 				if (strcmp ((gchar *) l->data, (gchar *) lang) == 0) {
120 					best_node = node;
121 					*best_lang_score = i;
122 				}
123 			}
124 		} else {
125 			if (best_node == NULL) {
126 				best_node = node;
127 			}
128 		}
129 		xmlFree (lang);
130 		if (*best_lang_score == 0) {
131 			return best_node;
132 		}
133 	}
134 
135 	return best_node;
136 }
137 
138 xmlNode *
139 e_xml_get_child_by_name_by_lang_list (const xmlNode *parent,
140                                       const gchar *name,
141                                       const GList *lang_list)
142 {
143 	gint best_lang_score = INT_MAX;
144 
145 	g_return_val_if_fail (parent != NULL, NULL);
146 	g_return_val_if_fail (name != NULL, NULL);
147 
148 	if (lang_list == NULL) {
149 		const gchar * const *language_names;
150 
151 		language_names = g_get_language_names ();
152 		while (*language_names != NULL)
153 			lang_list = g_list_append (
154 				(GList *) lang_list, (gchar *) * language_names++);
155 	}
156 	return e_xml_get_child_by_name_by_lang_list_with_score
157 		(parent,name,
158 		 lang_list,
159 		 &best_lang_score);
160 }
161 
162 xmlNode *
163 e_xml_get_child_by_name_no_lang (const xmlNode *parent,
164                                  const gchar *name)
165 {
166 	xmlNodePtr node;
167 
168 	g_return_val_if_fail (parent != NULL, NULL);
169 	g_return_val_if_fail (name != NULL, NULL);
170 
171 	for (node = parent->xmlChildrenNode; node != NULL; node = node->next) {
172 		xmlChar *lang;
173 
174 		if (node->name == NULL || strcmp ((gchar *) node->name, name) != 0) {
175 			continue;
176 		}
177 		lang = xmlGetProp (node, (const guchar *)"xml:lang");
178 		if (lang == NULL) {
179 			return node;
180 		}
181 		xmlFree (lang);
182 	}
183 
184 	return NULL;
185 }
186 
187 gint
188 e_xml_get_integer_prop_by_name (const xmlNode *parent,
189                                 const xmlChar *prop_name)
190 {
191 	g_return_val_if_fail (parent != NULL, 0);
192 	g_return_val_if_fail (prop_name != NULL, 0);
193 
194 	return e_xml_get_integer_prop_by_name_with_default (parent, prop_name, 0);
195 }
196 
197 gint
198 e_xml_get_integer_prop_by_name_with_default (const xmlNode *parent,
199                                              const xmlChar *prop_name,
200                                              gint def)
201 {
202 	xmlChar *prop;
203 	gint ret_val = def;
204 
205 	g_return_val_if_fail (parent != NULL, 0);
206 	g_return_val_if_fail (prop_name != NULL, 0);
207 
208 	prop = xmlGetProp ((xmlNode *) parent, prop_name);
209 	if (prop != NULL) {
210 		(void) sscanf ((gchar *) prop, "%d", &ret_val);
211 		xmlFree (prop);
212 	}
213 	return ret_val;
214 }
215 
216 void
217 e_xml_set_integer_prop_by_name (xmlNode *parent,
218                                 const xmlChar *prop_name,
219                                 gint value)
220 {
221 	gchar *valuestr;
222 
223 	g_return_if_fail (parent != NULL);
224 	g_return_if_fail (prop_name != NULL);
225 
226 	valuestr = g_strdup_printf ("%d", value);
227 	xmlSetProp (parent, prop_name, (guchar *) valuestr);
228 	g_free (valuestr);
229 }
230 
231 guint
232 e_xml_get_uint_prop_by_name (const xmlNode *parent,
233                              const xmlChar *prop_name)
234 {
235 	g_return_val_if_fail (parent != NULL, 0);
236 	g_return_val_if_fail (prop_name != NULL, 0);
237 
238 	return e_xml_get_uint_prop_by_name_with_default (parent, prop_name, 0);
239 }
240 
241 guint
242 e_xml_get_uint_prop_by_name_with_default (const xmlNode *parent,
243                                           const xmlChar *prop_name,
244                                           guint def)
245 {
246 	xmlChar *prop;
247 	guint ret_val = def;
248 
249 	g_return_val_if_fail (parent != NULL, 0);
250 	g_return_val_if_fail (prop_name != NULL, 0);
251 
252 	prop = xmlGetProp ((xmlNode *) parent, prop_name);
253 	if (prop != NULL) {
254 		(void) sscanf ((gchar *) prop, "%u", &ret_val);
255 		xmlFree (prop);
256 	}
257 	return ret_val;
258 }
259 
260 void
261 e_xml_set_uint_prop_by_name (xmlNode *parent,
262                              const xmlChar *prop_name,
263                              guint value)
264 {
265 	gchar *valuestr;
266 
267 	g_return_if_fail (parent != NULL);
268 	g_return_if_fail (prop_name != NULL);
269 
270 	valuestr = g_strdup_printf ("%u", value);
271 	xmlSetProp (parent, prop_name, (guchar *) valuestr);
272 	g_free (valuestr);
273 }
274 
275 gboolean
276 e_xml_get_bool_prop_by_name (const xmlNode *parent,
277                              const xmlChar *prop_name)
278 {
279 	g_return_val_if_fail (parent != NULL, 0);
280 	g_return_val_if_fail (prop_name != NULL, 0);
281 
282 	return e_xml_get_bool_prop_by_name_with_default (
283 		parent, prop_name, FALSE);
284 }
285 
286 gboolean
287 e_xml_get_bool_prop_by_name_with_default (const xmlNode *parent,
288                                           const xmlChar *prop_name,
289                                           gboolean def)
290 {
291 	xmlChar *prop;
292 	gboolean ret_val = def;
293 
294 	g_return_val_if_fail (parent != NULL, 0);
295 	g_return_val_if_fail (prop_name != NULL, 0);
296 
297 	prop = xmlGetProp ((xmlNode *) parent, prop_name);
298 	if (prop != NULL) {
299 		if (g_ascii_strcasecmp ((gchar *) prop, "true") == 0) {
300 			ret_val = TRUE;
301 		} else if (g_ascii_strcasecmp ((gchar *) prop, "false") == 0) {
302 			ret_val = FALSE;
303 		}
304 		xmlFree (prop);
305 	}
306 	return ret_val;
307 }
308 
309 void
310 e_xml_set_bool_prop_by_name (xmlNode *parent,
311                              const xmlChar *prop_name,
312                              gboolean value)
313 {
314 	g_return_if_fail (parent != NULL);
315 	g_return_if_fail (prop_name != NULL);
316 
317 	if (value) {
318 		xmlSetProp (parent, prop_name, (const guchar *)"true");
319 	} else {
320 		xmlSetProp (parent, prop_name, (const guchar *)"false");
321 	}
322 }
323 
324 gdouble
325 e_xml_get_double_prop_by_name (const xmlNode *parent,
326                                const xmlChar *prop_name)
327 {
328 	g_return_val_if_fail (parent != NULL, 0);
329 	g_return_val_if_fail (prop_name != NULL, 0);
330 
331 	return e_xml_get_double_prop_by_name_with_default (parent, prop_name, 0.0);
332 }
333 
334 gdouble
335 e_xml_get_double_prop_by_name_with_default (const xmlNode *parent,
336                                             const xmlChar *prop_name,
337                                             gdouble def)
338 {
339 	xmlChar *prop;
340 	gdouble ret_val = def;
341 
342 	g_return_val_if_fail (parent != NULL, 0);
343 	g_return_val_if_fail (prop_name != NULL, 0);
344 
345 	prop = xmlGetProp ((xmlNode *) parent, prop_name);
346 	if (prop != NULL) {
347 		ret_val = e_flexible_strtod ((gchar *) prop, NULL);
348 		xmlFree (prop);
349 	}
350 	return ret_val;
351 }
352 
353 void
354 e_xml_set_double_prop_by_name (xmlNode *parent,
355                                const xmlChar *prop_name,
356                                gdouble value)
357 {
358 	gchar buffer[E_ASCII_DTOSTR_BUF_SIZE];
359 	gchar *format;
360 
361 	g_return_if_fail (parent != NULL);
362 	g_return_if_fail (prop_name != NULL);
363 
364 	if (fabs (value) < 1e9 && fabs (value) > 1e-5) {
365 		format = g_strdup_printf ("%%.%df", DBL_DIG);
366 	} else {
367 		format = g_strdup_printf ("%%.%dg", DBL_DIG);
368 	}
369 	e_ascii_dtostr (buffer, sizeof (buffer), format, value);
370 	g_free (format);
371 
372 	xmlSetProp (parent, prop_name, (const guchar *) buffer);
373 }
374 
375 gchar *
376 e_xml_get_string_prop_by_name (const xmlNode *parent,
377                                const xmlChar *prop_name)
378 {
379 	g_return_val_if_fail (parent != NULL, NULL);
380 	g_return_val_if_fail (prop_name != NULL, NULL);
381 
382 	return e_xml_get_string_prop_by_name_with_default (parent, prop_name, NULL);
383 }
384 
385 gchar *
386 e_xml_get_string_prop_by_name_with_default (const xmlNode *parent,
387                                             const xmlChar *prop_name,
388                                             const gchar *def)
389 {
390 	xmlChar *prop;
391 	gchar *ret_val;
392 
393 	g_return_val_if_fail (parent != NULL, NULL);
394 	g_return_val_if_fail (prop_name != NULL, NULL);
395 
396 	prop = xmlGetProp ((xmlNode *) parent, prop_name);
397 	if (prop != NULL) {
398 		ret_val = g_strdup ((gchar *) prop);
399 		xmlFree (prop);
400 	} else {
401 		ret_val = g_strdup (def);
402 	}
403 	return ret_val;
404 }
405 
406 void
407 e_xml_set_string_prop_by_name (xmlNode *parent,
408                                const xmlChar *prop_name,
409                                const gchar *value)
410 {
411 	g_return_if_fail (parent != NULL);
412 	g_return_if_fail (prop_name != NULL);
413 
414 	if (value != NULL) {
415 		xmlSetProp (parent, prop_name, (guchar *) value);
416 	}
417 }
418 
419 gchar *
420 e_xml_get_translated_string_prop_by_name (const xmlNode *parent,
421                                           const xmlChar *prop_name)
422 {
423 	xmlChar *prop;
424 	gchar *ret_val = NULL;
425 	gchar *combined_name;
426 
427 	g_return_val_if_fail (parent != NULL, NULL);
428 	g_return_val_if_fail (prop_name != NULL, NULL);
429 
430 	prop = xmlGetProp ((xmlNode *) parent, prop_name);
431 	if (prop != NULL) {
432 		ret_val = g_strdup ((gchar *) prop);
433 		xmlFree (prop);
434 		return ret_val;
435 	}
436 
437 	combined_name = g_strdup_printf ("_%s", prop_name);
438 	prop = xmlGetProp ((xmlNode *) parent, (guchar *) combined_name);
439 	if (prop != NULL) {
440 		ret_val = g_strdup (gettext ((gchar *) prop));
441 		xmlFree (prop);
442 	}
443 	g_free (combined_name);
444 
445 	return ret_val;
446 }