2009-04-25 12:09:47 +04:00
|
|
|
/*
|
|
|
|
Search text engine.
|
|
|
|
Common share code for module.
|
|
|
|
|
2024-01-01 09:46:17 +03:00
|
|
|
Copyright (C) 2009-2024
|
2014-02-12 10:33:10 +04:00
|
|
|
Free Software Foundation, Inc.
|
2009-04-25 12:09:47 +04:00
|
|
|
|
|
|
|
Written by:
|
2013-08-09 09:22:24 +04:00
|
|
|
Slava Zanko <slavazanko@gmail.com>, 2009, 2011
|
|
|
|
Andrew Borodin <aborodin@vmail.ru>, 2013
|
2009-04-25 12:09:47 +04:00
|
|
|
|
|
|
|
This file is part of the Midnight Commander.
|
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander is free software: you can redistribute it
|
2009-04-25 12:09:47 +04:00
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
2011-10-15 14:56:47 +04:00
|
|
|
published by the Free Software Foundation, either version 3 of the License,
|
|
|
|
or (at your option) any later version.
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander 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.
|
2009-04-25 12:09:47 +04:00
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2011-10-15 14:56:47 +04:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-04-25 12:09:47 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
2009-09-22 13:35:09 +04:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2010-01-20 18:11:52 +03:00
|
|
|
#include "lib/global.h"
|
2010-01-21 15:17:26 +03:00
|
|
|
#include "lib/strutil.h"
|
2010-01-21 16:06:15 +03:00
|
|
|
#include "lib/search.h"
|
2012-04-30 15:52:39 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
|
|
|
#include "lib/charsets.h"
|
|
|
|
#endif
|
2010-01-21 15:17:26 +03:00
|
|
|
|
2010-01-07 02:57:27 +03:00
|
|
|
#include "internal.h"
|
2009-04-25 12:09:47 +04:00
|
|
|
|
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/* *INDENT-OFF* */
|
2010-11-08 13:21:45 +03:00
|
|
|
const char *STR_E_NOTFOUND = N_("Search string not found");
|
|
|
|
const char *STR_E_UNKNOWN_TYPE = N_("Not implemented yet");
|
|
|
|
const char *STR_E_RPL_NOT_EQ_TO_FOUND =
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
N_("Num of replace tokens not equal to num of found tokens");
|
2010-11-08 13:21:45 +03:00
|
|
|
const char *STR_E_RPL_INVALID_TOKEN = N_("Invalid token number %d");
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/* *INDENT-ON* */
|
2009-04-25 17:53:05 +04:00
|
|
|
|
2009-04-25 12:09:47 +04:00
|
|
|
/*** file scope macro definitions ****************************************************************/
|
|
|
|
|
|
|
|
/*** file scope type declarations ****************************************************************/
|
|
|
|
|
2022-09-18 15:04:13 +03:00
|
|
|
typedef gboolean (*case_conv_fn) (const char *ch, char **out, size_t * remain);
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
|
2009-04-25 12:09:47 +04:00
|
|
|
/*** file scope variables ************************************************************************/
|
|
|
|
|
2022-09-18 15:04:13 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2009-04-25 12:09:47 +04:00
|
|
|
/*** file scope functions ************************************************************************/
|
2022-09-18 15:04:13 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static GString *
|
2022-09-24 09:26:03 +03:00
|
|
|
mc_search__change_case_str (const char *charset, const GString * str, case_conv_fn case_conv)
|
2022-09-18 15:04:13 +03:00
|
|
|
{
|
|
|
|
GString *ret;
|
2022-09-24 09:26:03 +03:00
|
|
|
const char *src_ptr;
|
2022-09-18 16:31:18 +03:00
|
|
|
gchar *dst_str;
|
|
|
|
gchar *dst_ptr;
|
|
|
|
gsize dst_len;
|
2022-09-18 15:04:13 +03:00
|
|
|
#ifdef HAVE_CHARSET
|
2022-09-18 17:04:53 +03:00
|
|
|
GString *converted_str;
|
2022-09-18 15:04:13 +03:00
|
|
|
|
|
|
|
if (charset == NULL)
|
|
|
|
charset = cp_source;
|
|
|
|
|
2022-09-24 09:26:03 +03:00
|
|
|
converted_str = mc_search__recode_str (str->str, str->len, charset, cp_display);
|
2022-09-18 15:04:13 +03:00
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
dst_len = converted_str->len + 1; /* +1 is required for str_toupper/str_tolower */
|
2023-01-14 13:20:30 +03:00
|
|
|
dst_str = g_malloc (dst_len);
|
2022-09-18 15:04:13 +03:00
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
for (src_ptr = converted_str->str, dst_ptr = dst_str;
|
2022-09-18 16:31:18 +03:00
|
|
|
case_conv (src_ptr, &dst_ptr, &dst_len); src_ptr += str_length_char (src_ptr))
|
|
|
|
;
|
|
|
|
*dst_ptr = '\0';
|
2022-09-18 15:04:13 +03:00
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
dst_len = converted_str->len;
|
|
|
|
g_string_free (converted_str, TRUE);
|
2022-09-18 15:04:13 +03:00
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
ret = mc_search__recode_str (dst_str, dst_len, cp_display, charset);
|
2022-09-18 16:31:18 +03:00
|
|
|
g_free (dst_str);
|
|
|
|
#else
|
2022-09-18 15:04:13 +03:00
|
|
|
(void) charset;
|
|
|
|
|
2022-09-24 09:26:03 +03:00
|
|
|
dst_len = str->len + 1; /* +1 is required for str_toupper/str_tolower */
|
2023-01-14 13:20:30 +03:00
|
|
|
dst_str = g_malloc (dst_len);
|
2022-09-18 15:04:13 +03:00
|
|
|
|
2022-09-24 09:26:03 +03:00
|
|
|
for (src_ptr = str->str, dst_ptr = dst_str;
|
|
|
|
case_conv (src_ptr, &dst_ptr, &dst_len); src_ptr += str_length_char (src_ptr))
|
2022-09-18 16:31:18 +03:00
|
|
|
;
|
|
|
|
*dst_ptr = '\0';
|
2022-09-18 15:04:13 +03:00
|
|
|
|
2022-09-18 16:31:18 +03:00
|
|
|
ret = g_string_new_len (dst_str, dst_len);
|
|
|
|
g_free (dst_str);
|
2022-09-18 15:04:13 +03:00
|
|
|
#endif
|
2022-09-18 16:31:18 +03:00
|
|
|
return ret;
|
2022-09-18 15:04:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2009-04-25 12:09:47 +04:00
|
|
|
/*** public functions ****************************************************************************/
|
2022-09-18 15:04:13 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
GString *
|
|
|
|
mc_search__recode_str (const char *str, gsize str_len, const char *charset_from,
|
|
|
|
const char *charset_to)
|
2009-04-25 12:09:47 +04:00
|
|
|
{
|
2022-09-18 17:04:53 +03:00
|
|
|
GString *ret = NULL;
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2018-01-21 11:25:25 +03:00
|
|
|
if (charset_from != NULL && charset_to != NULL
|
|
|
|
&& g_ascii_strcasecmp (charset_to, charset_from) != 0)
|
2010-11-08 13:21:45 +03:00
|
|
|
{
|
2018-01-21 11:25:25 +03:00
|
|
|
GIConv conv;
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2018-01-21 11:25:25 +03:00
|
|
|
conv = g_iconv_open (charset_to, charset_from);
|
|
|
|
if (conv != INVALID_CONV)
|
|
|
|
{
|
2022-09-18 17:04:53 +03:00
|
|
|
gchar *val;
|
|
|
|
gsize bytes_read = 0;
|
|
|
|
gsize bytes_written = 0;
|
|
|
|
|
|
|
|
val = g_convert_with_iconv (str, str_len, conv, &bytes_read, &bytes_written, NULL);
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2018-01-21 11:25:25 +03:00
|
|
|
g_iconv_close (conv);
|
2022-09-18 17:04:53 +03:00
|
|
|
|
|
|
|
if (val != NULL)
|
|
|
|
{
|
|
|
|
ret = g_string_new_len (val, bytes_written);
|
|
|
|
g_free (val);
|
|
|
|
}
|
2018-01-21 11:25:25 +03:00
|
|
|
}
|
|
|
|
}
|
2009-12-04 12:27:24 +03:00
|
|
|
|
2010-11-08 13:21:45 +03:00
|
|
|
if (ret == NULL)
|
2022-09-18 17:04:53 +03:00
|
|
|
ret = g_string_new_len (str, str_len);
|
2009-12-04 12:27:24 +03:00
|
|
|
|
2009-04-25 12:09:47 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
GString *
|
2009-04-25 12:09:47 +04:00
|
|
|
mc_search__get_one_symbol (const char *charset, const char *str, gsize str_len,
|
|
|
|
gboolean * just_letters)
|
|
|
|
{
|
2022-09-18 17:04:53 +03:00
|
|
|
GString *converted_str;
|
2016-02-20 11:56:23 +03:00
|
|
|
const gchar *next_char;
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2009-05-07 13:20:34 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2022-09-18 17:04:53 +03:00
|
|
|
GString *converted_str2;
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2009-06-08 14:54:35 +04:00
|
|
|
if (charset == NULL)
|
|
|
|
charset = cp_source;
|
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
converted_str = mc_search__recode_str (str, str_len, charset, cp_display);
|
2009-05-07 13:20:34 +04:00
|
|
|
#else
|
2009-11-20 12:11:31 +03:00
|
|
|
(void) charset;
|
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
converted_str = g_string_new_len (str, str_len);
|
2009-05-07 13:20:34 +04:00
|
|
|
#endif
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2022-09-18 17:04:53 +03:00
|
|
|
next_char = str_cget_next_char (converted_str->str);
|
|
|
|
g_string_set_size (converted_str, (gsize) (next_char - converted_str->str));
|
2009-04-25 12:09:47 +04:00
|
|
|
|
2009-05-07 13:20:34 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2009-04-25 12:09:47 +04:00
|
|
|
converted_str2 =
|
2022-09-18 17:04:53 +03:00
|
|
|
mc_search__recode_str (converted_str->str, converted_str->len, cp_display, charset);
|
2009-05-07 13:20:34 +04:00
|
|
|
#endif
|
2018-01-21 11:11:56 +03:00
|
|
|
if (just_letters != NULL)
|
2022-09-18 17:04:53 +03:00
|
|
|
*just_letters = str_isalnum (converted_str->str) && !str_isdigit (converted_str->str);
|
2009-05-07 13:20:34 +04:00
|
|
|
#ifdef HAVE_CHARSET
|
2022-09-18 17:04:53 +03:00
|
|
|
g_string_free (converted_str, TRUE);
|
2009-04-25 12:09:47 +04:00
|
|
|
return converted_str2;
|
2009-05-07 13:20:34 +04:00
|
|
|
#else
|
|
|
|
return converted_str;
|
|
|
|
#endif
|
2009-04-25 12:09:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-08 21:50:15 +03:00
|
|
|
|
2009-04-25 12:09:47 +04:00
|
|
|
GString *
|
2022-09-24 09:26:03 +03:00
|
|
|
mc_search__tolower_case_str (const char *charset, const GString * str)
|
2009-04-25 12:09:47 +04:00
|
|
|
{
|
2022-09-24 09:26:03 +03:00
|
|
|
return mc_search__change_case_str (charset, str, str_tolower);
|
2009-04-25 12:09:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
GString *
|
2022-09-24 09:26:03 +03:00
|
|
|
mc_search__toupper_case_str (const char *charset, const GString * str)
|
2009-04-25 12:09:47 +04:00
|
|
|
{
|
2022-09-24 09:26:03 +03:00
|
|
|
return mc_search__change_case_str (charset, str, str_toupper);
|
2009-04-25 12:09:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-05-06 11:50:12 +04:00
|
|
|
gchar **
|
2010-11-08 13:21:45 +03:00
|
|
|
mc_search_get_types_strings_array (size_t * num)
|
2009-05-06 11:50:12 +04:00
|
|
|
{
|
|
|
|
gchar **ret;
|
2009-10-30 04:12:04 +03:00
|
|
|
int lc_index;
|
2009-09-22 13:35:09 +04:00
|
|
|
size_t n;
|
|
|
|
|
2009-05-08 16:23:38 +04:00
|
|
|
const mc_search_type_str_t *type_str;
|
2009-09-22 13:35:09 +04:00
|
|
|
const mc_search_type_str_t *types_str = mc_search_types_list_get (&n);
|
2009-05-06 11:50:12 +04:00
|
|
|
|
2009-12-12 13:54:22 +03:00
|
|
|
ret = g_try_new0 (char *, n + 1);
|
2009-08-05 17:07:51 +04:00
|
|
|
if (ret == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2010-11-08 13:21:45 +03:00
|
|
|
for (lc_index = 0, type_str = types_str; type_str->str != NULL; type_str++, lc_index++)
|
2009-10-30 04:12:04 +03:00
|
|
|
ret[lc_index] = g_strdup (type_str->str);
|
2009-09-22 13:35:09 +04:00
|
|
|
|
|
|
|
/* don't count last NULL item */
|
|
|
|
if (num != NULL)
|
2010-11-08 13:21:45 +03:00
|
|
|
*num = (size_t) lc_index;
|
2009-08-05 17:07:51 +04:00
|
|
|
|
2009-05-06 11:50:12 +04:00
|
|
|
return ret;
|
|
|
|
}
|
2009-06-09 13:01:00 +04:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|