Replace uses of g_strcasecmp() with our own implementation, utils_str_casecmp().

Add utils_str_casecmp() to the plugin API.

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3210 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2008-11-11 19:18:51 +00:00
parent 7009116b1a
commit d1b5ace11c
7 changed files with 79 additions and 10 deletions

View File

@ -9,6 +9,11 @@
* src/utils.c:
Evaluate only the strings 'TRUE' and 'true' to true in utils_atob(),
any other string is treated as false.
* src/document.c, src/plugindata.h, src/plugins.c, src/templates.c,
src/utils.c, src/utils.h:
Replace uses of g_strcasecmp() with our own implementation,
utils_str_casecmp().
Add utils_str_casecmp() to the plugin API.
2008-11-11 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>

View File

@ -104,7 +104,7 @@ static gboolean update_tags_from_buffer(GeanyDocument *doc);
/* ignore the case of filenames and paths under WIN32, causes errors if not */
#ifdef G_OS_WIN32
#define filenamecmp(a,b) strcasecmp((a), (b))
#define filenamecmp(a,b) utils_str_casecmp((a), (b))
#else
#define filenamecmp(a,b) strcmp((a), (b))
#endif
@ -983,13 +983,13 @@ static gboolean auto_update_tag_list(gpointer data)
if (! doc || ! doc->is_valid || doc->tm_file == NULL)
return FALSE;
if (gtk_window_get_focus(GTK_WINDOW(main_widgets.window)) != GTK_WIDGET(doc->editor->sci))
return TRUE;
if (update_tags_from_buffer(doc))
treeviews_update_tag_list(doc, TRUE);
return TRUE;
}
#endif

View File

@ -44,7 +44,7 @@
enum {
/** The Application Programming Interface (API) version, incremented
* whenever any plugin data types are modified or appended to. */
GEANY_API_VERSION = 106,
GEANY_API_VERSION = 107,
/** The Application Binary Interface (ABI) version, incremented whenever
* existing fields in the plugin data types have to be changed or reordered. */
@ -329,6 +329,7 @@ typedef struct UtilsFuncs
gboolean (*spawn_async) (const gchar *dir, gchar **argv, gchar **env, GSpawnFlags flags,
GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid,
GError **error);
gint (*utils_str_casecmp) (const gchar *s1, const gchar *s2);
}
UtilsFuncs;

View File

@ -198,7 +198,8 @@ static UtilsFuncs utils_funcs = {
&utils_get_setting_integer,
&utils_get_setting_string,
&utils_spawn_sync,
&utils_spawn_async
&utils_spawn_async,
&utils_str_casecmp
};
static UIUtilsFuncs uiutils_funcs = {
@ -745,7 +746,7 @@ load_plugins_from_path(const gchar *path)
for (item = list; item != NULL; item = g_slist_next(item))
{
tmp = strrchr(item->data, '.');
if (tmp == NULL || strcasecmp(tmp, "." PLUGIN_EXT) != 0)
if (tmp == NULL || utils_str_casecmp(tmp, "." PLUGIN_EXT) != 0)
continue;
fname = g_strconcat(path, G_DIR_SEPARATOR_S, item->data, NULL);

View File

@ -444,9 +444,9 @@ static gint compare_filenames_by_filetype(gconstpointer a, gconstpointer b)
if (ft_b->id == GEANY_FILETYPES_NONE)
return 1;
return g_strcasecmp(ft_a->name, ft_b->name);
return utils_str_casecmp(ft_a->name, ft_b->name);
}
return g_strcasecmp(a, b);
return utils_str_casecmp(a, b);
}

View File

@ -326,12 +326,72 @@ gdouble utils_scale_round(gdouble val, gdouble factor)
}
/**
* A replacement function for g_strncasecmp() to compare strings case-insensitive.
* It converts both strings into lowercase using g_utf8_strdown() and then compare
* both strings using strcmp().
* This is not completely accurate regarding locale-specific case sorting rules
* but seems to be a good compromise between correctness and performance.
*
* The input strings should be in UTF-8 or locale encoding.
*
* @param s1 Pointer to first string or @a NULL.
* @param s2 Pointer to second string or @a NULL.
*
* @return an integer less than, equal to, or greater than zero if @a s1 is found, respectively,
* to be less than, to match, or to be greater than @a s2.
**/
gint utils_str_casecmp(const gchar *s1, const gchar *s2)
{
gchar *tmp1, *tmp2, *ltmp1, *ltmp2;
gsize len1, len2;
gint result;
g_return_val_if_fail(s1 != NULL, 1);
g_return_val_if_fail(s2 != NULL, -1);
len1 = strlen(s1);
len2 = strlen(s2);
ltmp1 = g_strdup(s1);
ltmp2 = g_strdup(s2);
/* first ensure strings are UTF-8 */
if (! g_utf8_validate(s1, len1, NULL))
setptr(ltmp1, g_locale_to_utf8(s1, len1, NULL, NULL, NULL));
if (! g_utf8_validate(s2, len2, NULL))
setptr(ltmp2, g_locale_to_utf8(s2, len2, NULL, NULL, NULL));
if (ltmp1 == NULL);
{
utils_free_pointers(ltmp1, ltmp2, NULL);
return 1;
}
if (ltmp2 == NULL);
{
utils_free_pointers(ltmp1, ltmp2, NULL);
return -1;
}
/* then convert the strings into a case-insensitive form */
tmp1 = g_utf8_strdown(ltmp1, -1);
tmp2 = g_utf8_strdown(ltmp2, -1);
/* compare */
result = strcmp(tmp1, tmp2);
utils_free_pointers(tmp1, tmp2, ltmp1, ltmp2, NULL);
return result;
}
/**
* @a NULL-safe string comparison. Returns @a TRUE if both @c a and @c b are @a NULL
* or if @c a and @c b refer to valid strings which are equal.
*
* @param a Pointer to first string or @a NULL.
* @param b Pointer to first string or @a NULL.
* @param b Pointer to second string or @a NULL.
*
* @return @a TRUE if @c a equals @c b, else @a FALSE.
**/
@ -1337,7 +1397,7 @@ GSList *utils_get_file_list(const gchar *path, guint *length, GError **error)
const gchar *filename = g_dir_read_name(dir);
if (filename == NULL) break;
list = g_slist_insert_sorted(list, g_strdup(filename), (GCompareFunc) g_strcasecmp);
list = g_slist_insert_sorted(list, g_strdup(filename), (GCompareFunc) utils_str_casecmp);
len++;
}
g_dir_close(dir);

View File

@ -141,4 +141,6 @@ gboolean utils_spawn_async(const gchar *dir, gchar **argv, gchar **env, GSpawnFl
GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid,
GError **error);
gint utils_str_casecmp(const gchar *s1, const gchar *s2);
#endif