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-2022
   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 const char *STR_E_NOTFOUND = N_("Search string not found");
  45 const char *STR_E_UNKNOWN_TYPE = N_("Not implemented yet");
  46 const char *STR_E_RPL_NOT_EQ_TO_FOUND =
  47 N_("Num of replace tokens not equal to num of found tokens");
  48 const char *STR_E_RPL_INVALID_TOKEN = N_("Invalid token number %d");
  49 
  50 /*** file scope macro definitions ****************************************************************/
  51 
  52 /*** file scope type declarations ****************************************************************/
  53 
  54 typedef gboolean (*case_conv_fn) (const char *ch, char **out, size_t * remain);
  55 
  56 /*** file scope variables ************************************************************************/
  57 
  58 /* --------------------------------------------------------------------------------------------- */
  59 /*** file scope functions ************************************************************************/
  60 /* --------------------------------------------------------------------------------------------- */
  61 
  62 static GString *
  63 mc_search__change_case_str (const char *charset, const GString * str, case_conv_fn case_conv)
     /* [previous][next][first][last][top][bottom][index][help]  */
  64 {
  65     GString *ret;
  66     const char *src_ptr;
  67     gchar *dst_str;
  68     gchar *dst_ptr;
  69     gsize dst_len;
  70 #ifdef HAVE_CHARSET
  71     GString *converted_str;
  72 
  73     if (charset == NULL)
  74         charset = cp_source;
  75 
  76     converted_str = mc_search__recode_str (str->str, str->len, charset, cp_display);
  77 
  78     dst_str = g_malloc (converted_str->len);
  79     dst_len = converted_str->len + 1;   /* +1 is required for str_toupper/str_tolower */
  80 
  81     for (src_ptr = converted_str->str, dst_ptr = dst_str;
  82          case_conv (src_ptr, &dst_ptr, &dst_len); src_ptr += str_length_char (src_ptr))
  83         ;
  84     *dst_ptr = '\0';
  85 
  86     dst_len = converted_str->len;
  87     g_string_free (converted_str, TRUE);
  88 
  89     ret = mc_search__recode_str (dst_str, dst_len, cp_display, charset);
  90     g_free (dst_str);
  91 #else
  92     (void) charset;
  93 
  94     dst_str = g_malloc (str->len);
  95     dst_len = str->len + 1;     /* +1 is required for str_toupper/str_tolower */
  96 
  97     for (src_ptr = str->str, dst_ptr = dst_str;
  98          case_conv (src_ptr, &dst_ptr, &dst_len); src_ptr += str_length_char (src_ptr))
  99         ;
 100     *dst_ptr = '\0';
 101 
 102     ret = g_string_new_len (dst_str, dst_len);
 103     g_free (dst_str);
 104 #endif
 105     return ret;
 106 }
 107 
 108 /* --------------------------------------------------------------------------------------------- */
 109 /*** public functions ****************************************************************************/
 110 /* --------------------------------------------------------------------------------------------- */
 111 
 112 GString *
 113 mc_search__recode_str (const char *str, gsize str_len, const char *charset_from,
     /* [previous][next][first][last][top][bottom][index][help]  */
 114                        const char *charset_to)
 115 {
 116     GString *ret = NULL;
 117 
 118     if (charset_from != NULL && charset_to != NULL
 119         && g_ascii_strcasecmp (charset_to, charset_from) != 0)
 120     {
 121         GIConv conv;
 122 
 123         conv = g_iconv_open (charset_to, charset_from);
 124         if (conv != INVALID_CONV)
 125         {
 126             gchar *val;
 127             gsize bytes_read = 0;
 128             gsize bytes_written = 0;
 129 
 130             val = g_convert_with_iconv (str, str_len, conv, &bytes_read, &bytes_written, NULL);
 131 
 132             g_iconv_close (conv);
 133 
 134             if (val != NULL)
 135             {
 136                 ret = g_string_new_len (val, bytes_written);
 137                 g_free (val);
 138             }
 139         }
 140     }
 141 
 142     if (ret == NULL)
 143         ret = g_string_new_len (str, str_len);
 144 
 145     return ret;
 146 }
 147 
 148 /* --------------------------------------------------------------------------------------------- */
 149 
 150 GString *
 151 mc_search__get_one_symbol (const char *charset, const char *str, gsize str_len,
     /* [previous][next][first][last][top][bottom][index][help]  */
 152                            gboolean * just_letters)
 153 {
 154     GString *converted_str;
 155     const gchar *next_char;
 156 
 157 #ifdef HAVE_CHARSET
 158     GString *converted_str2;
 159 
 160     if (charset == NULL)
 161         charset = cp_source;
 162 
 163     converted_str = mc_search__recode_str (str, str_len, charset, cp_display);
 164 #else
 165     (void) charset;
 166 
 167     converted_str = g_string_new_len (str, str_len);
 168 #endif
 169 
 170     next_char = str_cget_next_char (converted_str->str);
 171     g_string_set_size (converted_str, (gsize) (next_char - converted_str->str));
 172 
 173 #ifdef HAVE_CHARSET
 174     converted_str2 =
 175         mc_search__recode_str (converted_str->str, converted_str->len, cp_display, charset);
 176 #endif
 177     if (just_letters != NULL)
 178         *just_letters = str_isalnum (converted_str->str) && !str_isdigit (converted_str->str);
 179 #ifdef HAVE_CHARSET
 180     g_string_free (converted_str, TRUE);
 181     return converted_str2;
 182 #else
 183     return converted_str;
 184 #endif
 185 }
 186 
 187 /* --------------------------------------------------------------------------------------------- */
 188 
 189 GString *
 190 mc_search__tolower_case_str (const char *charset, const GString * str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 191 {
 192     return mc_search__change_case_str (charset, str, str_tolower);
 193 }
 194 
 195 /* --------------------------------------------------------------------------------------------- */
 196 
 197 GString *
 198 mc_search__toupper_case_str (const char *charset, const GString * str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 199 {
 200     return mc_search__change_case_str (charset, str, str_toupper);
 201 }
 202 
 203 /* --------------------------------------------------------------------------------------------- */
 204 
 205 gchar **
 206 mc_search_get_types_strings_array (size_t * num)
     /* [previous][next][first][last][top][bottom][index][help]  */
 207 {
 208     gchar **ret;
 209     int lc_index;
 210     size_t n;
 211 
 212     const mc_search_type_str_t *type_str;
 213     const mc_search_type_str_t *types_str = mc_search_types_list_get (&n);
 214 
 215     ret = g_try_new0 (char *, n + 1);
 216     if (ret == NULL)
 217         return NULL;
 218 
 219     for (lc_index = 0, type_str = types_str; type_str->str != NULL; type_str++, lc_index++)
 220         ret[lc_index] = g_strdup (type_str->str);
 221 
 222     /* don't count last NULL item */
 223     if (num != NULL)
 224         *num = (size_t) lc_index;
 225 
 226     return ret;
 227 }
 228 
 229 /* --------------------------------------------------------------------------------------------- */

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