diff options
author | Marco Pesenti Gritti <mpeseng@src.gnome.org> | 2002-12-31 03:29:24 +0800 |
---|---|---|
committer | Marco Pesenti Gritti <mpeseng@src.gnome.org> | 2002-12-31 03:29:24 +0800 |
commit | 6876ede98282c7db318089bfefb292aa59e55d48 (patch) | |
tree | 76b23252d04da232d0ebf22e53bfe3e022686af9 /lib/ephy-string.c | |
download | gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.gz gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.bz2 gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.lz gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.xz gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.zst gsoc2013-epiphany-6876ede98282c7db318089bfefb292aa59e55d48.zip |
Initial revision
Diffstat (limited to 'lib/ephy-string.c')
-rw-r--r-- | lib/ephy-string.c | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/lib/ephy-string.c b/lib/ephy-string.c new file mode 100644 index 000000000..7ca28cf1f --- /dev/null +++ b/lib/ephy-string.c @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2002 Marco Pesenti Gritti + * + * 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; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-string.h" + +#include <string.h> +#include <glib.h> +#include <libgnome/libgnome.h> +#include <libgnome/gnome-i18n.h> +#include <libgnomevfs/gnome-vfs-mime.h> +#include <libxml/parser.h> + +/** + * ephy_string_shorten: returns a newly allocated shortened version of str. + * the new string will be no longer than target_length characters, and will + * be of the form "http://blahblah...blahblah.html". + */ +gchar * +ephy_string_shorten (const gchar *str, gint target_length) +{ + gchar *new_str; + gint actual_length, first_length, second_length; + + if (!str) return NULL; + + actual_length = strlen (str); + + /* if the string is already short enough, or if it's too short for + * us to shorten it, return a new copy */ + if (actual_length <= target_length || + actual_length <= 3) + return g_strdup (str); + + /* allocate new string */ + new_str = g_new (gchar, target_length + 1); + + /* calc lengths to take from beginning and ending of str */ + second_length = (target_length - 3) / 2; + first_length = target_length - 3 - second_length; + + /* create string */ + strncpy (new_str, str, first_length); + strncpy (new_str + first_length, "...", 3); + strncpy (new_str + first_length + 3, + str + actual_length - second_length, second_length); + new_str[target_length] = '\0'; + + return new_str; +} + +char * +ephy_string_double_underscores (const char *string) +{ + int underscores; + const char *p; + char *q; + char *escaped; + + if (string == NULL) { + return NULL; + } + + underscores = 0; + for (p = string; *p != '\0'; p++) { + underscores += (*p == '_'); + } + + if (underscores == 0) { + return g_strdup (string); + } + + escaped = g_new (char, strlen (string) + underscores + 1); + for (p = string, q = escaped; *p != '\0'; p++, q++) { + /* Add an extra underscore. */ + if (*p == '_') { + *q++ = '_'; + } + *q = *p; + } + *q = '\0'; + + return escaped; +} + +/** + * ephy_string_store_time_in_string: + * NOTE: str must be at least 256 chars long + */ +void +ephy_string_store_time_in_string (GDate *t, gchar *str, const char *format) +{ + int length; + + if (t > 0) + { + /* format into string */ + /* this is used whenever a brief date is needed, like + * in the history (for last visited, first time visited) */ + length = g_date_strftime (str, 255, + format ? format : _("%Y-%m-%d"), t); + str[length] = '\0'; + } + else + { + str[0] = '\0'; + } +} + +/** + * ephy_string_time_to_string: + */ +gchar * +ephy_string_time_to_string (GDate *t, + const char *format) +{ + gchar str[256]; + + /* write into stack string */ + ephy_string_store_time_in_string (t, str, format); + + /* copy in heap and return */ + return g_strdup (str); +} + +gboolean +ephy_str_to_int (const char *string, int *integer) +{ + long result; + char *parse_end; + + /* Check for the case of an empty string. */ + if (string == NULL || *string == '\0') { + return FALSE; + } + + /* Call the standard library routine to do the conversion. */ + errno = 0; + result = strtol (string, &parse_end, 0); + + /* Check that the result is in range. */ + if ((result == G_MINLONG || result == G_MAXLONG) && errno == ERANGE) { + return FALSE; + } + if (result < G_MININT || result > G_MAXINT) { + return FALSE; + } + + /* Check that all the trailing characters are spaces. */ + while (*parse_end != '\0') { + if (!g_ascii_isspace (*parse_end++)) { + return FALSE; + } + } + + /* Return the result. */ + *integer = result; + return TRUE; +} + +/** + * ephy_str_strip_chr: + * Remove all occurrences of a character from a string. + * + * @source: The string to be stripped. + * @remove_this: The char to remove from @source + * + * Return value: A copy of @source, after removing all occurrences + * of @remove_this. + */ +char * +ephy_str_strip_chr (const char *source, char remove_this) +{ + char *result, *out; + const char *in; + + if (source == NULL) { + return NULL; + } + + result = g_new (char, strlen (source) + 1); + in = source; + out = result; + do { + if (*in != remove_this) { + *out++ = *in; + } + } while (*in++ != '\0'); + + return result; +} + +int +ephy_strcasecmp (const char *string_a, const char *string_b) +{ + return g_ascii_strcasecmp (string_a == NULL ? "" : string_a, + string_b == NULL ? "" : string_b); +} + +int +ephy_strcasecmp_compare_func (gconstpointer string_a, gconstpointer string_b) +{ + return ephy_strcasecmp ((const char *) string_a, + (const char *) string_b); +} + +/** + * like strpbrk but ignores chars preceded by slashes, unless the + * slash is also preceded by a slash unless that later slash is + * preceded by another slash... ;-) + */ +static char * +ephy_strpbrk_unescaped (const char *s, const char *accept) +{ + gchar *ret = strpbrk (s, accept); + + if (!ret || ret == s || *(ret - 1) != '\\') + { + return ret; + } + else + { + gchar *c = ret - 1; + g_assert (*c == '\\'); + + while (c >= s && *c == '\\') c--; + + if ((ret - c) % 2 == 0) + { + return ephy_strpbrk_unescaped (ret + 1, accept); + } + else + { + return ret; + } + } +} + +/** + * like strstr but supports quoting, ignoring matches inside quoted text + */ +static char * +ephy_strstr_with_quotes (const char *haystack, const char *needle, + const char *quotes) +{ + gchar *quot = ephy_strpbrk_unescaped (haystack, quotes); + gchar *ret = strstr (haystack, needle); + + if (!quot || !ret || ret < quot) + { + return ret; + } + + quot = ephy_strpbrk_unescaped (quot + 1, quotes); + + if (quot) + { + return ephy_strstr_with_quotes (quot + 1, needle, quotes); + } + else + { + return NULL; + } +} + +/** + * like strpbrk but supports quoting, ignoring matches inside quoted text + */ +static char * +ephy_strpbrk_with_quotes (const char *haystack, const char *needles, + const char *quotes) +{ + gchar *quot = ephy_strpbrk_unescaped (haystack, quotes); + gchar *ret = strpbrk (haystack, needles); + + if (!quot || !ret || ret < quot) + { + return ret; + } + + quot = ephy_strpbrk_unescaped (quot + 1, quotes); + + if (quot) + { + return ephy_strpbrk_with_quotes (quot + 1, needles, quotes); + } + else + { + return NULL; + } +} + +/** + * Like g_strsplit, but does not split tokens betwen quotes. Ignores + * quotes preceded by '\'. + */ +gchar ** +ephy_strsplit_with_quotes (const gchar *string, + const gchar *delimiter, + gint max_tokens, + const gchar *quotes) +{ + GSList *string_list = NULL, *slist; + gchar **str_array, *s; + guint n = 0; + const gchar *remainder; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != '\0', NULL); + + if (quotes == NULL) + { + return g_strsplit (string, delimiter, max_tokens); + } + + if (max_tokens < 1) + { + max_tokens = G_MAXINT; + } + + remainder = string; + s = ephy_strstr_with_quotes (remainder, delimiter, quotes); + if (s) + { + gsize delimiter_len = strlen (delimiter); + + while (--max_tokens && s) + { + gsize len; + gchar *new_string; + + len = s - remainder; + new_string = g_new (gchar, len + 1); + strncpy (new_string, remainder, len); + new_string[len] = 0; + string_list = g_slist_prepend (string_list, new_string); + n++; + remainder = s + delimiter_len; + s = ephy_strstr_with_quotes (remainder, delimiter, quotes); + } + } + if (*string) + { + n++; + string_list = g_slist_prepend (string_list, g_strdup (remainder)); + } + + str_array = g_new (gchar*, n + 1); + + str_array[n--] = NULL; + for (slist = string_list; slist; slist = slist->next) + { + str_array[n--] = slist->data; + } + + g_slist_free (string_list); + + return str_array; +} + +/** + * like ephy_strsplit_with_quotes, but matches any char in 'delimiters' as delimiter + * and does not return empty tokens + */ +gchar ** +ephy_strsplit_multiple_delimiters_with_quotes (const gchar *string, + const gchar *delimiters, + gint max_tokens, + const gchar *quotes) +{ + GSList *string_list = NULL, *slist; + gchar **str_array, *s; + guint n = 0; + const gchar *remainder; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiters != NULL, NULL); + g_return_val_if_fail (delimiters[0] != '\0', NULL); + + if (quotes == NULL) + { + quotes = ""; + } + + if (max_tokens < 1) + { + max_tokens = G_MAXINT; + } + + remainder = string; + s = ephy_strpbrk_with_quotes (remainder, delimiters, quotes); + if (s) + { + const gsize delimiter_len = 1; /* only chars */ + + while (--max_tokens && s) + { + gsize len; + gchar *new_string; + + len = s - remainder; + if (len > 0) /* ignore empty strings */ + { + new_string = g_new (gchar, len + 1); + strncpy (new_string, remainder, len); + new_string[len] = 0; + string_list = g_slist_prepend (string_list, new_string); + n++; + } + remainder = s + delimiter_len; + s = ephy_strpbrk_with_quotes (remainder, delimiters, quotes); + } + } + if (*string) + { + n++; + string_list = g_slist_prepend (string_list, g_strdup (remainder)); + } + + str_array = g_new (gchar*, n + 1); + + str_array[n--] = NULL; + for (slist = string_list; slist; slist = slist->next) + { + str_array[n--] = slist->data; + } + + g_slist_free (string_list); + + return str_array; +} |