From 9c0a8e7d3f5eaf09d1f86f082b3c7ce821e113ae Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Tue, 22 Sep 2009 13:35:09 +0400 Subject: [PATCH] Fixed segfault in search in editor and viewer. Modified API of search engine: return the number of search types. This avoids the calculation of the search type count when need. Sync editor search, editor replace and viewer searc dialogs with new search API. Fixed memory leak in editcmd_dialog_search_show(). Signed-off-by: Andrew Borodin --- edit/editcmd_dialogs.c | 28 +++++++++++++++++++++------- src/search/lib.c | 23 ++++++++++++++++------- src/search/search.c | 8 +++++++- src/search/search.h | 6 ++++-- src/viewer/dialogs.c | 19 +++++++++++++------ 5 files changed, 61 insertions(+), 23 deletions(-) diff --git a/edit/editcmd_dialogs.c b/edit/editcmd_dialogs.c index 22ce0d002..48f07fcbc 100644 --- a/edit/editcmd_dialogs.c +++ b/edit/editcmd_dialogs.c @@ -89,8 +89,9 @@ editcmd_dialog_replace_show (WEdit * edit, const char *search_default, const cha search_default = INPUT_LAST_TEXT; { - gchar **list_of_types = mc_search_get_types_strings_array(); - int REPLACE_DLG_HEIGHT = REPLACE_DLG_MIN_HEIGHT + g_strv_length (list_of_types) - REPLACE_DLG_HEIGHT_SUPPLY; + size_t num_of_types; + gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types); + int REPLACE_DLG_HEIGHT = REPLACE_DLG_MIN_HEIGHT + num_of_types - REPLACE_DLG_HEIGHT_SUPPLY; QuickWidget quick_widgets[] = { @@ -104,7 +105,7 @@ editcmd_dialog_replace_show (WEdit * edit, const char *search_default, const cha /* 5 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 8, REPLACE_DLG_HEIGHT, N_("&Backwards"), &edit->replace_backwards), /* 6 */ QUICK_CHECKBOX (33, REPLACE_DLG_WIDTH, 7, REPLACE_DLG_HEIGHT, N_("case &Sensitive"), &edit->replace_case), /* 7 */ QUICK_RADIO (3, REPLACE_DLG_WIDTH, 7, REPLACE_DLG_HEIGHT, - g_strv_length (list_of_types), (const char **) list_of_types, &edit->search_type), + num_of_types, (const char **) list_of_types, &edit->search_type), /* 8 */ QUICK_LABEL (2, REPLACE_DLG_WIDTH, 4, REPLACE_DLG_HEIGHT, N_(" Enter replacement string:")), /* 9 */ QUICK_INPUT (3, REPLACE_DLG_WIDTH, 5, REPLACE_DLG_HEIGHT, replace_default, REPLACE_DLG_WIDTH - 6, 0, "replace", replace_text), @@ -140,9 +141,10 @@ editcmd_dialog_search_show (WEdit * edit, char **search_text) *search_text = INPUT_LAST_TEXT; { + size_t num_of_types; + gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types); + int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + num_of_types - SEARCH_DLG_HEIGHT_SUPPLY; int i; - gchar **list_of_types = mc_search_get_types_strings_array(); - int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + g_strv_length (list_of_types) - SEARCH_DLG_HEIGHT_SUPPLY; int dialog_result; @@ -168,7 +170,7 @@ editcmd_dialog_search_show (WEdit * edit, char **search_text) QUICK_CHECKBOX (33, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"), &edit->replace_case), /* 8 */ QUICK_RADIO ( 3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, - g_strv_length (list_of_types), (const char **) list_of_types, &edit->search_type), + num_of_types, (const char **) list_of_types, &edit->search_type), /* 9 */ QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT, *search_text, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, search_text), @@ -189,8 +191,9 @@ editcmd_dialog_search_show (WEdit * edit, char **search_text) "[Input Line Keys]", quick_widgets, TRUE }; - #ifdef ENABLE_NLS + char **list_of_types_nls; + /* header title */ Quick_input.title = _(Quick_input.title); /* buttons */ @@ -201,6 +204,15 @@ editcmd_dialog_search_show (WEdit * edit, char **search_text) quick_widgets[i].u.checkbox.text = _(quick_widgets[i].u.checkbox.text); /* label */ quick_widgets[10].u.label.text = _(quick_widgets[10].u.label.text); + + /* radiobuttons */ + /* create copy of radio items to avoid memory leak */ + list_of_types_nls = g_new0 (char *, num_of_types + 1); + for (i = 0; i < num_of_types; i++) + list_of_types_nls[i] = g_strdup (_(list_of_types[i])); + g_strfreev (list_of_types); + list_of_types = list_of_types_nls; + quick_widgets[last_checkbox + 1].u.radio.items = (const char **) list_of_types; #endif /* calculate widget coordinates */ @@ -249,6 +261,8 @@ editcmd_dialog_search_show (WEdit * edit, char **search_text) dialog_result = quick_dialog (&Quick_input); + g_strfreev (list_of_types); + if (dialog_result == B_CANCEL) *search_text = NULL; else if (dialog_result == B_USER) diff --git a/src/search/lib.c b/src/search/lib.c index 7ceeb4994..93f5b28b3 100644 --- a/src/search/lib.c +++ b/src/search/lib.c @@ -27,6 +27,8 @@ #include +#include +#include #include "../src/global.h" #include "../src/search/search.h" @@ -241,20 +243,27 @@ mc_search__toupper_case_str (const char *charset, const char *str, gsize str_len /* --------------------------------------------------------------------------------------------- */ gchar ** -mc_search_get_types_strings_array (void) +mc_search_get_types_strings_array (size_t *num) { gchar **ret; int index; - const mc_search_type_str_t *type_str; - const mc_search_type_str_t *types_str = mc_search_types_list_get (); + size_t n; - ret = g_malloc0(sizeof(char**) * sizeof(types_str) ); + const mc_search_type_str_t *type_str; + const mc_search_type_str_t *types_str = mc_search_types_list_get (&n); + + ret = g_new0 (char *, n + 1); if (ret == NULL) return NULL; - for (index=0, type_str = types_str; type_str->str != NULL; type_str++, index++){ - ret[index] = g_strdup(_(type_str->str)); - } + for (index = 0, type_str = types_str; + type_str->str != NULL; + type_str++, index++) + ret[index] = g_strdup (type_str->str); + + /* don't count last NULL item */ + if (num != NULL) + *num = (size_t) index; return ret; } diff --git a/src/search/search.c b/src/search/search.c index 8d8f62063..1e9df0681 100644 --- a/src/search/search.c +++ b/src/search/search.c @@ -27,6 +27,8 @@ #include +#include +#include #include "../src/global.h" #include "../src/search/search.h" @@ -290,8 +292,12 @@ mc_search_is_type_avail (mc_search_type_t search_type) /* --------------------------------------------------------------------------------------------- */ const mc_search_type_str_t * -mc_search_types_list_get (void) +mc_search_types_list_get (size_t *num) { + /* don't count last NULL item */ + if (num != NULL) + *num = sizeof (mc_search__list_types) / sizeof (mc_search__list_types[0]) - 1; + return mc_search__list_types; } diff --git a/src/search/search.h b/src/search/search.h index ea9e9699f..176fcfaef 100644 --- a/src/search/search.h +++ b/src/search/search.h @@ -5,6 +5,8 @@ #include "../src/global.h" /* */ +#include + #ifdef SEARCH_TYPE_PCRE # include #endif @@ -125,14 +127,14 @@ gboolean mc_search_run (mc_search_t * mc_search, const void *user_data, gsize st gboolean mc_search_is_type_avail (mc_search_type_t); -const mc_search_type_str_t *mc_search_types_list_get (void); +const mc_search_type_str_t *mc_search_types_list_get (size_t *num); GString *mc_search_prepare_replace_str (mc_search_t * mc_search, GString * replace_str); char *mc_search_prepare_replace_str2 (mc_search_t *, char *); gboolean mc_search_is_fixed_search_str (mc_search_t *); -gchar **mc_search_get_types_strings_array (void); +gchar **mc_search_get_types_strings_array (size_t *num); gboolean mc_search (const gchar *, const gchar *, mc_search_type_t); diff --git a/src/viewer/dialogs.c b/src/viewer/dialogs.c index 2d45a5690..6de6e6ed8 100644 --- a/src/viewer/dialogs.c +++ b/src/viewer/dialogs.c @@ -37,12 +37,18 @@ #include +#include +#include + +#include "../src/search/search.h" + #include "../src/global.h" #include "../src/wtools.h" -#include "internal.h" #include "../src/history.h" #include "../src/charsets.h" +#include "internal.h" + /*** global variables ****************************************************************************/ /*** file scope macro definitions ****************************************************************/ @@ -67,11 +73,12 @@ mcview_dialog_search (mcview_t * view) char *exp = NULL; int qd_result; - gchar **list_of_types = mc_search_get_types_strings_array (); - int SEARCH_DLG_HEIGHT = - SEARCH_DLG_MIN_HEIGHT + g_strv_length (list_of_types) - SEARCH_DLG_HEIGHT_SUPPLY; + size_t num_of_types; + gchar **list_of_types = mc_search_get_types_strings_array (&num_of_types); + int SEARCH_DLG_HEIGHT = SEARCH_DLG_MIN_HEIGHT + num_of_types - SEARCH_DLG_HEIGHT_SUPPLY; - QuickWidget quick_widgets[] = { + QuickWidget quick_widgets[] = + { QUICK_BUTTON (6, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&Cancel"), B_CANCEL, NULL), QUICK_BUTTON (2, 10, SEARCH_DLG_HEIGHT - 3, SEARCH_DLG_HEIGHT, N_("&OK"), B_ENTER, NULL), #ifdef HAVE_CHARSET @@ -85,7 +92,7 @@ mcview_dialog_search (mcview_t * view) QUICK_CHECKBOX (SEARCH_DLG_WIDTH / 2 + 3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, N_("case &Sensitive"), &view->search_case), QUICK_RADIO (3, SEARCH_DLG_WIDTH, 5, SEARCH_DLG_HEIGHT, - g_strv_length (list_of_types), (const char **) list_of_types, &view->search_type), + num_of_types, (const char **) list_of_types, &view->search_type), QUICK_INPUT (3, SEARCH_DLG_WIDTH, 3, SEARCH_DLG_HEIGHT, INPUT_LAST_TEXT, SEARCH_DLG_WIDTH - 6, 0, MC_HISTORY_SHARED_SEARCH, &exp), QUICK_LABEL (2, SEARCH_DLG_WIDTH, 2, SEARCH_DLG_HEIGHT, N_(" Enter search string:")),