root/lib/search/lib.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. mc_search__change_case_str
  2. mc_search__recode_str
  3. mc_search__get_one_symbol
  4. mc_search__tolower_case_str
  5. mc_search__toupper_case_str
  6. mc_search_get_types_strings_array

   1 /*
   2    Search text engine.
   3    Common share code for module.
   4 
   5    Copyright (C) 2009-2024
   6    Free Software Foundation, Inc.
   7 
   8    Written by:
   9    Slava Zanko <slavazanko@gmail.com>, 2009, 2011
  10    Andrew Borodin <aborodin@vmail.ru>, 2013
  11 
  12    This file is part of the Midnight Commander.
  13 
  14    The Midnight Commander is free software: you can redistribute it
  15    and/or modify it under the terms of the GNU General Public License as
  16    published by the Free Software Foundation, either version 3 of the License,
  17    or (at your option) any later version.
  18 
  19    The Midnight Commander is distributed in the hope that it will be useful,
  20    but WITHOUT ANY WARRANTY; without even the implied warranty of
  21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22    GNU General Public License for more details.
  23 
  24    You should have received a copy of the GNU General Public License
  25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  26  */
  27 
  28 #include <config.h>
  29 
  30 #include <stdlib.h>
  31 #include <sys/types.h>
  32 
  33 #include "lib/global.h"
  34 #include "lib/strutil.h"
  35 #include "lib/search.h"
  36 #ifdef HAVE_CHARSET
  37 #include "lib/charsets.h"
  38 #endif
  39 
  40 #include "internal.h"
  41 
  42 /*** global variables ****************************************************************************/
  43 
  44 /* *INDENT-OFF* */
  45 const char *STR_E_NOTFOUND = N_("Search string not found");
  46 const char *STR_E_UNKNOWN_TYPE = N_("Not implemented yet");
  47 const char *STR_E_RPL_NOT_EQ_TO_FOUND =
  48             N_("Num of replace tokens not equal to num of found tokens");
  49 const char *STR_E_RPL_INVALID_TOKEN = N_("Invalid token number %d");
  50 /* *INDENT-ON* */
  51 
  52 /*** file scope macro definitions ****************************************************************/
  53 
  54 /*** file scope type declarations ****************************************************************/
  55 
  56 typedef gboolean (*case_conv_fn) (const char *ch, char **out, size_t *remain);
  57 
  58 /*** forward declarations (file scope functions) *************************************************/
  59 
  60 /*** file scope variables ************************************************************************/
  61 
  62 /* --------------------------------------------------------------------------------------------- */
  63 /*** file scope functions ************************************************************************/
  64 /* --------------------------------------------------------------------------------------------- */
  65 
  66 static GString *
  67 mc_search__change_case_str (const char *charset, const GString *str, case_conv_fn case_conv)
     /* [previous][next][first][last][top][bottom][index][help]  */
  68 {
  69     GString *ret;
  70     const char *src_ptr;
  71     gchar *dst_str;
  72     gchar *dst_ptr;
  73     gsize dst_len;
  74 #ifdef HAVE_CHARSET
  75     GString *converted_str;
  76 
  77     if (charset == NULL)
  78         charset = cp_source;
  79 
  80     converted_str = mc_search__recode_str (str->str, str->len, charset, cp_display);
  81 
  82     dst_len = converted_str->len + 1;   /* +1 is required for str_toupper/str_tolower */
  83     dst_str = g_malloc (dst_len);
  84 
  85     for (src_ptr = converted_str->str, dst_ptr = dst_str;
  86          case_conv (src_ptr, &dst_ptr, &dst_len); src_ptr += str_length_char (src_ptr))
  87         ;
  88     *dst_ptr = '\0';
  89 
  90     dst_len = converted_str->len;
  91     g_string_free (converted_str, TRUE);
  92 
  93     ret = mc_search__recode_str (dst_str, dst_len, cp_display, charset);
  94     g_free (dst_str);
  95 #else
  96     (void) charset;
  97 
  98     dst_len = str->len + 1;     /* +1 is required for str_toupper/str_tolower */
  99     dst_str = g_malloc (dst_len);
 100 
 101     for (src_ptr = str->str, dst_ptr = dst_str;
 102          case_conv (src_ptr, &dst_ptr, &dst_len); src_ptr += str_length_char (src_ptr))
 103         ;
 104     *dst_ptr = '\0';
 105 
 106     ret = g_string_new_len (dst_str, dst_len);
 107     g_free (dst_str);
 108 #endif
 109     return ret;
 110 }
 111 
 112 /* --------------------------------------------------------------------------------------------- */
 113 /*** public functions ****************************************************************************/
 114 /* --------------------------------------------------------------------------------------------- */
 115 
 116 GString *
 117 mc_search__recode_str (const char *str, gsize str_len, const char *charset_from,
     /* [previous][next][first][last][top][bottom][index][help]  */
 118                        const char *charset_to)
 119 {
 120     GString *ret = NULL;
 121 
 122     if (charset_from != NULL && charset_to != NULL
 123         && g_ascii_strcasecmp (charset_to, charset_from) != 0)
 124     {
 125         GIConv conv;
 126 
 127         conv = g_iconv_open (charset_to, charset_from);
 128         if (conv != INVALID_CONV)
 129         {
 130             gchar *val;
 131             gsize bytes_read = 0;
 132             gsize bytes_written = 0;
 133 
 134             val = g_convert_with_iconv (str, str_len, conv, &bytes_read, &bytes_written, NULL);
 135 
 136             g_iconv_close (conv);
 137 
 138             if (val != NULL)
 139             {
 140                 ret = g_string_new_len (val, bytes_written);
 141                 g_free (val);
 142             }
 143         }
 144     }
 145 
 146     if (ret == NULL)
 147         ret = g_string_new_len (str, str_len);
 148 
 149     return ret;
 150 }
 151 
 152 /* --------------------------------------------------------------------------------------------- */
 153 
 154 GString *
 155 mc_search__get_one_symbol (const char *charset, const char *str, gsize str_len,
     /* [previous][next][first][last][top][bottom][index][help]  */
 156                            gboolean *just_letters)
 157 {
 158     GString *converted_str;
 159     const gchar *next_char;
 160 
 161 #ifdef HAVE_CHARSET
 162     GString *converted_str2;
 163 
 164     if (charset == NULL)
 165         charset = cp_source;
 166 
 167     converted_str = mc_search__recode_str (str, str_len, charset, cp_display);
 168 #else
 169     (void) charset;
 170 
 171     converted_str = g_string_new_len (str, str_len);
 172 #endif
 173 
 174     next_char = str_cget_next_char (converted_str->str);
 175     g_string_set_size (converted_str, (gsize) (next_char - converted_str->str));
 176 
 177 #ifdef HAVE_CHARSET
 178     converted_str2 =
 179         mc_search__recode_str (converted_str->str, converted_str->len, cp_display, charset);
 180 #endif
 181     if (just_letters != NULL)
 182         *just_letters = str_isalnum (converted_str->str) && !str_isdigit (converted_str->str);
 183 #ifdef HAVE_CHARSET
 184     g_string_free (converted_str, TRUE);
 185     return converted_str2;
 186 #else
 187     return converted_str;
 188 #endif
 189 }
 190 
 191 /* --------------------------------------------------------------------------------------------- */
 192 
 193 GString *
 194 mc_search__tolower_case_str (const char *charset, const GString *str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 195 {
 196     return mc_search__change_case_str (charset, str, str_tolower);
 197 }
 198 
 199 /* --------------------------------------------------------------------------------------------- */
 200 
 201 GString *
 202 mc_search__toupper_case_str (const char *charset, const GString *str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 203 {
 204     return mc_search__change_case_str (charset, str, str_toupper);
 205 }
 206 
 207 /* --------------------------------------------------------------------------------------------- */
 208 
 209 gchar **
 210 mc_search_get_types_strings_array (size_t *num)
     /* [previous][next][first][last][top][bottom][index][help]  */
 211 {
 212     gchar **ret;
 213     int lc_index;
 214     size_t n;
 215 
 216     const mc_search_type_str_t *type_str;
 217     const mc_search_type_str_t *types_str = mc_search_types_list_get (&n);
 218 
 219     ret = g_try_new0 (char *, n + 1);
 220     if (ret == NULL)
 221         return NULL;
 222 
 223     for (lc_index = 0, type_str = types_str; type_str->str != NULL; type_str++, lc_index++)
 224         ret[lc_index] = g_strdup (type_str->str);
 225 
 226     /* don't count last NULL item */
 227     if (num != NULL)
 228         *num = (size_t) lc_index;
 229 
 230     return ret;
 231 }
 232 
 233 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */