root/lib/search/glob.c

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

DEFINITIONS

This source file includes following definitions.
  1. mc_search__glob_translate_to_regex
  2. mc_search__translate_replace_glob_to_regex
  3. mc_search__cond_struct_new_init_glob
  4. mc_search__run_glob
  5. mc_search_glob_prepare_replace_str

   1 /*
   2    Search text engine.
   3    Glob-style pattern matching
   4 
   5    Copyright (C) 2009-2019
   6    Free Software Foundation, Inc.
   7 
   8    Written by:
   9    Slava Zanko <slavazanko@gmail.com>, 2009.
  10 
  11    This file is part of the Midnight Commander.
  12 
  13    The Midnight Commander is free software: you can redistribute it
  14    and/or modify it under the terms of the GNU General Public License as
  15    published by the Free Software Foundation, either version 3 of the License,
  16    or (at your option) any later version.
  17 
  18    The Midnight Commander is distributed in the hope that it will be useful,
  19    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21    GNU General Public License for more details.
  22 
  23    You should have received a copy of the GNU General Public License
  24    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  25  */
  26 
  27 #include <config.h>
  28 
  29 #include "lib/global.h"
  30 #include "lib/strutil.h"
  31 #include "lib/search.h"
  32 #include "lib/strescape.h"
  33 
  34 #include "internal.h"
  35 
  36 /*** global variables ****************************************************************************/
  37 
  38 /*** file scope macro definitions ****************************************************************/
  39 
  40 /*** file scope type declarations ****************************************************************/
  41 
  42 /*** file scope variables ************************************************************************/
  43 
  44 /*** file scope functions ************************************************************************/
  45 
  46 static GString *
  47 mc_search__glob_translate_to_regex (const GString * astr)
     /* [previous][next][first][last][top][bottom][index][help]  */
  48 {
  49     const char *str = astr->str;
  50     GString *buff;
  51     gsize loop;
  52     gboolean inside_group = FALSE;
  53 
  54     buff = g_string_sized_new (32);
  55 
  56     for (loop = 0; loop < astr->len; loop++)
  57     {
  58         switch (str[loop])
  59         {
  60         case '*':
  61             if (!strutils_is_char_escaped (str, &(str[loop])))
  62             {
  63                 g_string_append (buff, inside_group ? ".*" : "(.*)");
  64                 continue;
  65             }
  66             break;
  67         case '?':
  68             if (!strutils_is_char_escaped (str, &(str[loop])))
  69             {
  70                 g_string_append (buff, inside_group ? "." : "(.)");
  71                 continue;
  72             }
  73             break;
  74         case ',':
  75             if (!strutils_is_char_escaped (str, &(str[loop])))
  76             {
  77                 g_string_append_c (buff, inside_group ? '|' : ',');
  78                 continue;
  79             }
  80             break;
  81         case '{':
  82             if (!strutils_is_char_escaped (str, &(str[loop])))
  83             {
  84                 g_string_append_c (buff, '(');
  85                 inside_group = TRUE;
  86                 continue;
  87             }
  88             break;
  89         case '}':
  90             if (!strutils_is_char_escaped (str, &(str[loop])))
  91             {
  92                 g_string_append_c (buff, ')');
  93                 inside_group = FALSE;
  94                 continue;
  95             }
  96             break;
  97         case '+':
  98         case '.':
  99         case '$':
 100         case '(':
 101         case ')':
 102         case '^':
 103             g_string_append_c (buff, '\\');
 104             break;
 105         default:
 106             break;
 107         }
 108         g_string_append_c (buff, str[loop]);
 109     }
 110     return buff;
 111 }
 112 
 113 /* --------------------------------------------------------------------------------------------- */
 114 
 115 static GString *
 116 mc_search__translate_replace_glob_to_regex (const char *str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 117 {
 118     GString *buff;
 119     char cnt = '0';
 120     gboolean escaped_mode = FALSE;
 121 
 122     buff = g_string_sized_new (32);
 123 
 124     while (*str != '\0')
 125     {
 126         char c = *str++;
 127 
 128         switch (c)
 129         {
 130         case '\\':
 131             if (!escaped_mode)
 132             {
 133                 escaped_mode = TRUE;
 134                 g_string_append_c (buff, '\\');
 135                 continue;
 136             }
 137             break;
 138         case '*':
 139         case '?':
 140             if (!escaped_mode)
 141             {
 142                 g_string_append_c (buff, '\\');
 143                 c = ++cnt;
 144             }
 145             break;
 146         case '&':
 147             if (!escaped_mode)
 148                 g_string_append_c (buff, '\\');
 149             break;
 150         default:
 151             break;
 152         }
 153         g_string_append_c (buff, c);
 154         escaped_mode = FALSE;
 155     }
 156     return buff;
 157 }
 158 
 159 /*** public functions ****************************************************************************/
 160 
 161 void
 162 mc_search__cond_struct_new_init_glob (const char *charset, mc_search_t * lc_mc_search,
     /* [previous][next][first][last][top][bottom][index][help]  */
 163                                       mc_search_cond_t * mc_search_cond)
 164 {
 165     GString *tmp;
 166 
 167     tmp = mc_search__glob_translate_to_regex (mc_search_cond->str);
 168     g_string_free (mc_search_cond->str, TRUE);
 169 
 170     if (lc_mc_search->is_entire_line)
 171     {
 172         g_string_prepend_c (tmp, '^');
 173         g_string_append_c (tmp, '$');
 174     }
 175     mc_search_cond->str = tmp;
 176 
 177     mc_search__cond_struct_new_init_regex (charset, lc_mc_search, mc_search_cond);
 178 }
 179 
 180 /* --------------------------------------------------------------------------------------------- */
 181 
 182 gboolean
 183 mc_search__run_glob (mc_search_t * lc_mc_search, const void *user_data,
     /* [previous][next][first][last][top][bottom][index][help]  */
 184                      gsize start_search, gsize end_search, gsize * found_len)
 185 {
 186     return mc_search__run_regex (lc_mc_search, user_data, start_search, end_search, found_len);
 187 }
 188 
 189 /* --------------------------------------------------------------------------------------------- */
 190 
 191 GString *
 192 mc_search_glob_prepare_replace_str (mc_search_t * lc_mc_search, GString * replace_str)
     /* [previous][next][first][last][top][bottom][index][help]  */
 193 {
 194     GString *repl = mc_search__translate_replace_glob_to_regex (replace_str->str);
 195     GString *res = mc_search_regex_prepare_replace_str (lc_mc_search, repl);
 196     g_string_free (repl, TRUE);
 197     return res;
 198 }
 199 
 200 /* --------------------------------------------------------------------------------------------- */

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