diff options
Diffstat (limited to 'libevolution-utils')
-rw-r--r-- | libevolution-utils/Makefile.am | 12 | ||||
-rw-r--r-- | libevolution-utils/e-alert-dialog.c | 1 | ||||
-rw-r--r-- | libevolution-utils/e-alert-dialog.h | 2 | ||||
-rw-r--r-- | libevolution-utils/e-alert-sink.h | 2 | ||||
-rw-r--r-- | libevolution-utils/e-alert.c | 2 | ||||
-rw-r--r-- | libevolution-utils/e-xml-utils.c | 2 | ||||
-rw-r--r-- | libevolution-utils/evolution-util.c | 260 | ||||
-rw-r--r-- | libevolution-utils/evolution-util.h | 42 |
8 files changed, 316 insertions, 7 deletions
diff --git a/libevolution-utils/Makefile.am b/libevolution-utils/Makefile.am index a0b44bf370..82798ad144 100644 --- a/libevolution-utils/Makefile.am +++ b/libevolution-utils/Makefile.am @@ -13,10 +13,20 @@ libevolution_utils_la_CPPFLAGS = \ libevolutionutilsincludedir = $(privincludedir)/libevolution-utils libevolutionutilsinclude_HEADERS = \ + e-alert.h \ + e-alert-dialog.h \ + e-alert-sink.h \ + e-xml-utils.h \ + evolution-util.h \ $(NULL) libevolution_utils_la_SOURCES = \ - $(libevolutionutilsinclude_HEADERS) \ + $(libevolutionutilsinclude_HEADERS) \ + e-alert.c \ + e-alert-dialog.c \ + e-alert-sink.c \ + e-xml-utils.c \ + evolution-util.c \ $(NULL) libevolution_utils_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) diff --git a/libevolution-utils/e-alert-dialog.c b/libevolution-utils/e-alert-dialog.c index 5f426aacd0..e5c2164089 100644 --- a/libevolution-utils/e-alert-dialog.c +++ b/libevolution-utils/e-alert-dialog.c @@ -29,7 +29,6 @@ #include "e-alert-dialog.h" -#include "e-util.h" #define E_ALERT_DIALOG_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ diff --git a/libevolution-utils/e-alert-dialog.h b/libevolution-utils/e-alert-dialog.h index a8d1b1d6d5..cfdcca5875 100644 --- a/libevolution-utils/e-alert-dialog.h +++ b/libevolution-utils/e-alert-dialog.h @@ -25,7 +25,7 @@ #define E_ALERT_DIALOG_H #include <gtk/gtk.h> -#include <e-util/e-alert.h> +#include <libevolution-utils/e-alert.h> /* Standard GObject macros */ #define E_TYPE_ALERT_DIALOG \ diff --git a/libevolution-utils/e-alert-sink.h b/libevolution-utils/e-alert-sink.h index da5ae7b06f..73199c1e2e 100644 --- a/libevolution-utils/e-alert-sink.h +++ b/libevolution-utils/e-alert-sink.h @@ -20,7 +20,7 @@ #define E_ALERT_SINK_H #include <gtk/gtk.h> -#include <e-util/e-alert.h> +#include <libevolution-utils/e-alert.h> /* Standard GObject macros */ #define E_TYPE_ALERT_SINK \ diff --git a/libevolution-utils/e-alert.c b/libevolution-utils/e-alert.c index 9ee7e05581..7171e743a3 100644 --- a/libevolution-utils/e-alert.c +++ b/libevolution-utils/e-alert.c @@ -37,8 +37,6 @@ #include <libedataserver/e-xml-utils.h> -#include "e-util.h" -#include "e-util-private.h" #include "e-alert.h" #include "e-alert-sink.h" diff --git a/libevolution-utils/e-xml-utils.c b/libevolution-utils/e-xml-utils.c index 0247f91e27..21c39aa514 100644 --- a/libevolution-utils/e-xml-utils.c +++ b/libevolution-utils/e-xml-utils.c @@ -41,7 +41,7 @@ #include <libxml/parser.h> #include <libxml/xmlmemory.h> -#include "e-util.h" +#include "evolution-util.h" #include "e-xml-utils.h" /* Returns the first child with the name child_name and the "lang" diff --git a/libevolution-utils/evolution-util.c b/libevolution-utils/evolution-util.c new file mode 100644 index 0000000000..23d3b51efa --- /dev/null +++ b/libevolution-utils/evolution-util.c @@ -0,0 +1,260 @@ +/* + * 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. + * + * 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. + * + * 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/> + * + * + * Authors: + Srinivasa Ragavan <sragavan@gnome.org> + * + * Copyright (C) 2012 Intel Corporation (www.intel.com) + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <ctype.h> +#include <math.h> +#include <string.h> +#include <locale.h> + +#include "evolution-util.h" + +/** + * e_flexible_strtod: + * @nptr: the string to convert to a numeric value. + * @endptr: if non-NULL, it returns the character after + * the last character used in the conversion. + * + * Converts a string to a gdouble value. This function detects + * strings either in the standard C locale or in the current locale. + * + * This function is typically used when reading configuration files or + * other non-user input that should not be locale dependent, but may + * have been in the past. To handle input from the user you should + * normally use the locale-sensitive system strtod function. + * + * To convert from a double to a string in a locale-insensitive way, use + * @g_ascii_dtostr. + * + * Returns: the gdouble value + **/ + +gdouble +e_flexible_strtod (const gchar *nptr, + gchar **endptr) +{ + gchar *fail_pos; + gdouble val; + struct lconv *locale_data; + const gchar *decimal_point; + gint decimal_point_len; + const gchar *p, *decimal_point_pos; + const gchar *end = NULL; /* Silence gcc */ + gchar *copy, *c; + + g_return_val_if_fail (nptr != NULL, 0); + + fail_pos = NULL; + + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen (decimal_point); + + g_return_val_if_fail (decimal_point_len != 0, 0); + + decimal_point_pos = NULL; + if (!strcmp (decimal_point, ".")) + return strtod (nptr, endptr); + + p = nptr; + + /* Skip leading space */ + while (isspace ((guchar) * p)) + p++; + + /* Skip leading optional sign */ + if (*p == '+' || *p == '-') + p++; + + if (p[0] == '0' && + (p[1] == 'x' || p[1] == 'X')) { + p += 2; + /* HEX - find the (optional) decimal point */ + + while (isxdigit ((guchar) * p)) + p++; + + if (*p == '.') { + decimal_point_pos = p++; + + while (isxdigit ((guchar) * p)) + p++; + + if (*p == 'p' || *p == 'P') + p++; + if (*p == '+' || *p == '-') + p++; + while (isdigit ((guchar) * p)) + p++; + end = p; + } else if (strncmp (p, decimal_point, decimal_point_len) == 0) { + return strtod (nptr, endptr); + } + } else { + while (isdigit ((guchar) * p)) + p++; + + if (*p == '.') { + decimal_point_pos = p++; + + while (isdigit ((guchar) * p)) + p++; + + if (*p == 'e' || *p == 'E') + p++; + if (*p == '+' || *p == '-') + p++; + while (isdigit ((guchar) * p)) + p++; + end = p; + } else if (strncmp (p, decimal_point, decimal_point_len) == 0) { + return strtod (nptr, endptr); + } + } + /* For the other cases, we need not convert the decimal point */ + + if (!decimal_point_pos) + return strtod (nptr, endptr); + + /* We need to convert the '.' to the locale specific decimal point */ + copy = g_malloc (end - nptr + 1 + decimal_point_len); + + c = copy; + memcpy (c, nptr, decimal_point_pos - nptr); + c += decimal_point_pos - nptr; + memcpy (c, decimal_point, decimal_point_len); + c += decimal_point_len; + memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); + c += end - (decimal_point_pos + 1); + *c = 0; + + val = strtod (copy, &fail_pos); + + if (fail_pos) { + if (fail_pos > decimal_point_pos) + fail_pos = + (gchar *) nptr + (fail_pos - copy) - + (decimal_point_len - 1); + else + fail_pos = (gchar *) nptr + (fail_pos - copy); + } + + g_free (copy); + + if (endptr) + *endptr = fail_pos; + + return val; +} + +/** + * e_ascii_dtostr: + * @buffer: A buffer to place the resulting string in + * @buf_len: The length of the buffer. + * @format: The printf-style format to use for the + * code to use for converting. + * @d: The double to convert + * + * Converts a double to a string, using the '.' as + * decimal_point. To format the number you pass in + * a printf-style formating string. Allowed conversion + * specifiers are eEfFgG. + * + * If you want to generates enough precision that converting + * the string back using @g_strtod gives the same machine-number + * (on machines with IEEE compatible 64bit doubles) use the format + * string "%.17g". If you do this it is guaranteed that the size + * of the resulting string will never be larger than + * @G_ASCII_DTOSTR_BUF_SIZE bytes. + * + * Returns: the pointer to the buffer with the converted string + **/ +gchar * +e_ascii_dtostr (gchar *buffer, + gint buf_len, + const gchar *format, + gdouble d) +{ + struct lconv *locale_data; + const gchar *decimal_point; + gint decimal_point_len; + gchar *p; + gint rest_len; + gchar format_char; + + g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (format[0] == '%', NULL); + g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); + + format_char = format[strlen (format) - 1]; + + g_return_val_if_fail (format_char == 'e' || format_char == 'E' || + format_char == 'f' || format_char == 'F' || + format_char == 'g' || format_char == 'G', + NULL); + + if (format[0] != '%') + return NULL; + + if (strpbrk (format + 1, "'l%")) + return NULL; + + if (!(format_char == 'e' || format_char == 'E' || + format_char == 'f' || format_char == 'F' || + format_char == 'g' || format_char == 'G')) + return NULL; + + g_snprintf (buffer, buf_len, format, d); + + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen (decimal_point); + + g_return_val_if_fail (decimal_point_len != 0, NULL); + + if (strcmp (decimal_point, ".")) { + p = buffer; + + if (*p == '+' || *p == '-') + p++; + + while (isdigit ((guchar) * p)) + p++; + + if (strncmp (p, decimal_point, decimal_point_len) == 0) { + *p = '.'; + p++; + if (decimal_point_len > 1) { + rest_len = strlen (p + (decimal_point_len - 1)); + memmove (p, p + (decimal_point_len - 1), + rest_len); + p[rest_len] = 0; + } + } + } + + return buffer; +} + diff --git a/libevolution-utils/evolution-util.h b/libevolution-utils/evolution-util.h new file mode 100644 index 0000000000..5d1830bfae --- /dev/null +++ b/libevolution-utils/evolution-util.h @@ -0,0 +1,42 @@ +/* + * 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. + * + * 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. + * + * 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/> + * + * + * Authors: + Srinivasa Ragavan <sragavan@gnome.org> + * + * Copyright (C) 2012 Intel Corporation (www.intel.com) + * + */ + +#ifndef EVOLUTION_UTIL_H +#define EVOLUTION_UTIL_H + +#include <sys/types.h> +#include <glib.h> + +/* String to/from double conversion functions */ +gdouble e_flexible_strtod (const gchar *nptr, + gchar **endptr); + +/* 29 bytes should enough for all possible values that + * g_ascii_dtostr can produce with the %.17g format. + * Then add 10 for good measure */ +#define E_ASCII_DTOSTR_BUF_SIZE (DBL_DIG + 12 + 10) +gchar * e_ascii_dtostr (gchar *buffer, + gint buf_len, + const gchar *format, + gdouble d); + +#endif /* EVOLUTION_UTIL_H */ |