Manual pages: mcmcdiffmceditmcview

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

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