5 Copyright (C) 2009 The Free Software Foundation, Inc.
8 Slava Zanko <slavazanko@gmail.com>, 2009.
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software; you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be
18 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
19 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
31 #include "../src/global.h"
32 #include "../src/search/search.h"
33 #include "../src/search/internal.h"
34 #include "../src/strutil.h"
35 #include "../src/charsets.h"
37 /*** global variables ****************************************************************************/
39 /*** file scope macro definitions ****************************************************************/
41 /*** file scope type declarations ****************************************************************/
43 /*** file scope variables ************************************************************************/
45 static const mc_search_type_str_t mc_search__list_types
[] = {
46 {N_("Normal"), MC_SEARCH_T_NORMAL
},
47 {N_("&Regular expression"), MC_SEARCH_T_REGEX
},
48 {N_("Hexadecimal"), MC_SEARCH_T_HEX
},
49 {N_("Wildcard search"), MC_SEARCH_T_GLOB
},
53 /*** file scope functions ************************************************************************/
55 static mc_search_cond_t
*
56 mc_search__cond_struct_new (mc_search_t
* mc_search
, const char *str
,
57 gsize str_len
, const char *charset
)
59 mc_search_cond_t
*mc_search_cond
;
60 mc_search_cond
= g_malloc0 (sizeof (mc_search_cond_t
));
62 mc_search_cond
->str
= g_string_new_len (str
, str_len
);
63 mc_search_cond
->len
= str_len
;
64 mc_search_cond
->charset
= g_strdup (charset
);
66 switch (mc_search
->search_type
) {
67 case MC_SEARCH_T_GLOB
:
68 mc_search__cond_struct_new_init_glob (charset
, mc_search
, mc_search_cond
);
70 case MC_SEARCH_T_NORMAL
:
71 mc_search__cond_struct_new_init_normal (charset
, mc_search
, mc_search_cond
);
73 case MC_SEARCH_T_REGEX
:
74 mc_search__cond_struct_new_init_regex (charset
, mc_search
, mc_search_cond
);
77 mc_search__cond_struct_new_init_hex (charset
, mc_search
, mc_search_cond
);
82 return mc_search_cond
;
85 /* --------------------------------------------------------------------------------------------- */
88 mc_search__conditions_new (mc_search_t
* mc_search
)
91 ret
= g_ptr_array_new ();
93 if (mc_search
->is_all_charsets
) {
94 gsize loop1
, recoded_str_len
;
96 for (loop1
= 0; loop1
< (gsize
) n_codepages
; loop1
++) {
97 if (!g_ascii_strcasecmp (codepages
[loop1
].id
, cp_source
)) {
99 mc_search__cond_struct_new (mc_search
, mc_search
->original
,
100 mc_search
->original_len
, cp_source
));
105 mc_search__recode_str (mc_search
->original
, mc_search
->original_len
, cp_source
,
106 codepages
[loop1
].id
, &recoded_str_len
);
110 g_ptr_array_add (ret
,
111 mc_search__cond_struct_new (mc_search
, buffer
,
112 recoded_str_len
, codepages
[loop1
].id
));
116 g_ptr_array_add (ret
,
117 (gpointer
) mc_search__cond_struct_new (mc_search
, mc_search
->original
,
118 mc_search
->original_len
,
122 g_ptr_array_add (ret
,
123 (gpointer
) mc_search__cond_struct_new (mc_search
, mc_search
->original
,
124 mc_search
->original_len
,
125 str_detect_termencoding()));
130 /* --------------------------------------------------------------------------------------------- */
133 mc_search__cond_struct_free (mc_search_cond_t
* mc_search_cond
)
135 if (mc_search_cond
->upper
)
136 g_string_free (mc_search_cond
->upper
, TRUE
);
138 if (mc_search_cond
->lower
)
139 g_string_free (mc_search_cond
->lower
, TRUE
);
141 g_string_free (mc_search_cond
->str
, TRUE
);
142 g_free (mc_search_cond
->charset
);
144 #if GLIB_CHECK_VERSION (2, 14, 0)
145 if (mc_search_cond
->regex_handle
)
146 g_regex_unref (mc_search_cond
->regex_handle
);
147 #else /* GLIB_CHECK_VERSION (2, 14, 0) */
149 if (mc_search_cond
->regex_handle
)
150 free (mc_search_cond
->regex_handle
);
151 #else /* HAVE_LIBPCRE */
152 if (mc_search_cond
->regex_handle
)
153 regfree (mc_search_cond
->regex_handle
);
154 #endif /* HAVE_LIBPCRE */
155 #endif /* GLIB_CHECK_VERSION (2, 14, 0) */
157 g_free (mc_search_cond
);
160 /* --------------------------------------------------------------------------------------------- */
163 mc_search__conditions_free (GPtrArray
* array
)
166 mc_search_cond_t
*mc_search
;
168 for (loop1
= 0; loop1
< array
->len
; loop1
++) {
169 mc_search
= (mc_search_cond_t
*) g_ptr_array_index (array
, loop1
);
170 mc_search__cond_struct_free (mc_search
);
172 g_ptr_array_free (array
, TRUE
);
175 /* --------------------------------------------------------------------------------------------- */
179 /*** public functions ****************************************************************************/
182 mc_search_new (const gchar
* original
, gsize str_len
)
184 mc_search_t
*mc_search
;
188 if ((gssize
) str_len
== -1) {
189 str_len
= strlen (original
);
194 mc_search
= g_malloc0 (sizeof (mc_search_t
));
195 mc_search
->original
= g_strndup (original
, str_len
);
196 mc_search
->original_len
= str_len
;
200 /* --------------------------------------------------------------------------------------------- */
203 mc_search_free (mc_search_t
* mc_search
)
208 g_free (mc_search
->original
);
210 if (mc_search
->error_str
)
211 g_free (mc_search
->error_str
);
213 if (mc_search
->conditions
)
214 mc_search__conditions_free (mc_search
->conditions
);
216 #if GLIB_CHECK_VERSION (2, 14, 0)
217 if (mc_search
->regex_match_info
)
218 g_match_info_free (mc_search
->regex_match_info
);
219 #else /* GLIB_CHECK_VERSION (2, 14, 0) */
221 if (mc_search
->regex_match_info
)
222 free (mc_search
->regex_match_info
);
223 #else /* HAVE_LIBPCRE */
224 if (mc_search
->regex_match_info
)
225 g_free (mc_search
->regex_match_info
);
226 #endif /* HAVE_LIBPCRE */
227 #endif /* GLIB_CHECK_VERSION (2, 14, 0) */
229 if (mc_search
->regex_buffer
!= NULL
)
230 g_string_free (mc_search
->regex_buffer
, TRUE
);
235 /* --------------------------------------------------------------------------------------------- */
238 mc_search_run (mc_search_t
* mc_search
, const void *user_data
,
239 gsize start_search
, gsize end_search
, gsize
* found_len
)
241 gboolean ret
= FALSE
;
245 if (!mc_search_is_type_avail (mc_search
->search_type
)) {
246 mc_search
->error
= MC_SEARCH_E_INPUT
;
247 mc_search
->error_str
= g_strdup (_(STR_E_UNKNOWN_TYPE
));
250 #if GLIB_CHECK_VERSION (2, 14, 0)
251 if (mc_search
->regex_match_info
) {
252 g_match_info_free (mc_search
->regex_match_info
);
253 mc_search
->regex_match_info
= NULL
;
255 #endif /* GLIB_CHECK_VERSION (2, 14, 0) */
257 mc_search
->error
= MC_SEARCH_E_OK
;
258 if (mc_search
->error_str
) {
259 g_free (mc_search
->error_str
);
260 mc_search
->error_str
= NULL
;
263 if (!mc_search
->conditions
) {
264 mc_search
->conditions
= mc_search__conditions_new (mc_search
);
266 if (mc_search
->error
!= MC_SEARCH_E_OK
)
270 switch (mc_search
->search_type
) {
271 case MC_SEARCH_T_NORMAL
:
272 ret
= mc_search__run_normal (mc_search
, user_data
, start_search
, end_search
, found_len
);
274 case MC_SEARCH_T_REGEX
:
275 ret
= mc_search__run_regex (mc_search
, user_data
, start_search
, end_search
, found_len
);
277 case MC_SEARCH_T_GLOB
:
278 ret
= mc_search__run_glob (mc_search
, user_data
, start_search
, end_search
, found_len
);
280 case MC_SEARCH_T_HEX
:
281 ret
= mc_search__run_hex (mc_search
, user_data
, start_search
, end_search
, found_len
);
289 /* --------------------------------------------------------------------------------------------- */
292 mc_search_is_type_avail (mc_search_type_t search_type
)
294 switch (search_type
) {
295 case MC_SEARCH_T_GLOB
:
296 case MC_SEARCH_T_NORMAL
:
297 case MC_SEARCH_T_REGEX
:
298 case MC_SEARCH_T_HEX
:
307 /* --------------------------------------------------------------------------------------------- */
309 const mc_search_type_str_t
*
310 mc_search_types_list_get (void)
312 return mc_search__list_types
;
315 /* --------------------------------------------------------------------------------------------- */
318 mc_search_prepare_replace_str (mc_search_t
* mc_search
, GString
* replace_str
)
322 if (mc_search
== NULL
)
323 return g_string_new_len (replace_str
->str
, replace_str
->len
);
325 switch (mc_search
->search_type
) {
326 case MC_SEARCH_T_REGEX
:
327 ret
= mc_search_regex_prepare_replace_str (mc_search
, replace_str
);
329 case MC_SEARCH_T_NORMAL
:
330 case MC_SEARCH_T_HEX
:
331 case MC_SEARCH_T_GLOB
:
333 ret
= g_string_new_len (replace_str
->str
, replace_str
->len
);
339 /* --------------------------------------------------------------------------------------------- */
342 mc_search_is_fixed_search_str (mc_search_t
* mc_search
)
344 if (mc_search
== NULL
)
346 switch (mc_search
->search_type
) {
347 case MC_SEARCH_T_REGEX
:
348 case MC_SEARCH_T_GLOB
:
357 /* --------------------------------------------------------------------------------------------- */
360 mc_search (const gchar
*pattern
, const gchar
*str
, mc_search_type_t type
)
363 mc_search_t
*search
= mc_search_new(pattern
, -1);
366 search
->search_type
= type
;
367 search
->is_case_sentitive
= TRUE
;
368 ret
= mc_search_run(search
,str
,0,strlen(str
),NULL
);
369 mc_search_free(search
);
373 /* --------------------------------------------------------------------------------------------- */
376 mc_search_getstart_rezult_by_num(mc_search_t
*mc_search
, int index
)
380 if (mc_search
->search_type
== MC_SEARCH_T_NORMAL
)
382 #if GLIB_CHECK_VERSION (2, 14, 0)
385 g_match_info_fetch_pos (mc_search
->regex_match_info
, index
, &start_pos
, &end_pos
);
386 return (int) start_pos
;
387 #else /* GLIB_CHECK_VERSION (2, 14, 0) */
389 return mc_search
->iovector
[index
*2];
390 #else /* HAVE_LIBPCRE */
391 return mc_search
->regex_match_info
[index
].rm_so
;
392 #endif /* HAVE_LIBPCRE */
393 #endif /* GLIB_CHECK_VERSION (2, 14, 0) */
397 /* --------------------------------------------------------------------------------------------- */
400 mc_search_getend_rezult_by_num(mc_search_t
*mc_search
, int index
)
404 if (mc_search
->search_type
== MC_SEARCH_T_NORMAL
)
406 #if GLIB_CHECK_VERSION (2, 14, 0)
409 g_match_info_fetch_pos (mc_search
->regex_match_info
, index
, &start_pos
, &end_pos
);
410 return (int) end_pos
;
411 #else /* GLIB_CHECK_VERSION (2, 14, 0) */
413 return mc_search
->iovector
[index
*2+1];
414 #else /* HAVE_LIBPCRE */
415 return mc_search
->regex_match_info
[index
].rm_eo
;
416 #endif /* HAVE_LIBPCRE */
417 #endif /* GLIB_CHECK_VERSION (2, 14, 0) */
421 /* --------------------------------------------------------------------------------------------- */