This source file includes following definitions.
- mc_search__cond_struct_new
- mc_search__cond_struct_free
- mc_search_new
- mc_search_new_len
- mc_search_free
- mc_search_prepare
- mc_search_run
- mc_search_is_type_avail
- mc_search_types_list_get
- mc_search_prepare_replace_str
- mc_search_prepare_replace_str2
- mc_search_is_fixed_search_str
- mc_search
- mc_search_getstart_result_by_num
- mc_search_getend_result_by_num
- mc_search_set_error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <config.h>
29
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <sys/types.h>
33
34 #include "lib/global.h"
35 #include "lib/strutil.h"
36 #include "lib/search.h"
37 #include "lib/util.h"
38 #ifdef HAVE_CHARSET
39 #include "lib/charsets.h"
40 #endif
41
42 #include "internal.h"
43
44
45
46
47
48
49
50
51
52
53
54 static const mc_search_type_str_t mc_search__list_types[] = {
55 {N_("No&rmal"), MC_SEARCH_T_NORMAL},
56 {N_("Re&gular expression"), MC_SEARCH_T_REGEX},
57 {N_("He&xadecimal"), MC_SEARCH_T_HEX},
58 {N_("Wil&dcard search"), MC_SEARCH_T_GLOB},
59 {NULL, MC_SEARCH_T_INVALID}
60 };
61
62
63
64
65
66 static mc_search_cond_t *
67 mc_search__cond_struct_new (mc_search_t *lc_mc_search, const GString *str, const char *charset)
68 {
69 mc_search_cond_t *mc_search_cond;
70
71 mc_search_cond = g_malloc0 (sizeof (mc_search_cond_t));
72 mc_search_cond->str = mc_g_string_dup (str);
73 mc_search_cond->charset = g_strdup (charset);
74 #ifdef HAVE_PCRE2
75 lc_mc_search->regex_match_info = pcre2_match_data_create (MC_SEARCH__NUM_REPLACE_ARGS, NULL);
76 lc_mc_search->iovector = pcre2_get_ovector_pointer (lc_mc_search->regex_match_info);
77 #endif
78 switch (lc_mc_search->search_type)
79 {
80 case MC_SEARCH_T_GLOB:
81 mc_search__cond_struct_new_init_glob (charset, lc_mc_search, mc_search_cond);
82 break;
83 case MC_SEARCH_T_NORMAL:
84 mc_search__cond_struct_new_init_normal (charset, lc_mc_search, mc_search_cond);
85 break;
86 case MC_SEARCH_T_REGEX:
87 mc_search__cond_struct_new_init_regex (charset, lc_mc_search, mc_search_cond);
88 break;
89 case MC_SEARCH_T_HEX:
90 mc_search__cond_struct_new_init_hex (charset, lc_mc_search, mc_search_cond);
91 break;
92 default:
93 break;
94 }
95 return mc_search_cond;
96 }
97
98
99
100 static void
101 mc_search__cond_struct_free (gpointer data)
102 {
103 mc_search_cond_t *mc_search_cond = (mc_search_cond_t *) data;
104
105 if (mc_search_cond->upper != NULL)
106 g_string_free (mc_search_cond->upper, TRUE);
107
108 if (mc_search_cond->lower != NULL)
109 g_string_free (mc_search_cond->lower, TRUE);
110
111 g_string_free (mc_search_cond->str, TRUE);
112 g_free (mc_search_cond->charset);
113
114 #ifdef SEARCH_TYPE_GLIB
115 if (mc_search_cond->regex_handle != NULL)
116 g_regex_unref (mc_search_cond->regex_handle);
117 #else
118 g_free (mc_search_cond->regex_handle);
119 #endif
120
121 g_free (mc_search_cond);
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135 mc_search_t *
136 mc_search_new (const gchar *original, const gchar *original_charset)
137 {
138 if (original == NULL)
139 return NULL;
140
141 return mc_search_new_len (original, strlen (original), original_charset);
142 }
143
144
145
146
147
148
149
150
151
152
153
154 mc_search_t *
155 mc_search_new_len (const gchar *original, gsize original_len, const gchar *original_charset)
156 {
157 mc_search_t *lc_mc_search;
158
159 if (original == NULL || original_len == 0)
160 return NULL;
161
162 lc_mc_search = g_new0 (mc_search_t, 1);
163 lc_mc_search->original.str = g_string_new_len (original, original_len);
164 #ifdef HAVE_CHARSET
165 lc_mc_search->original.charset =
166 g_strdup (original_charset != NULL
167 && *original_charset != '\0' ? original_charset : cp_display);
168 #else
169 (void) original_charset;
170 #endif
171
172 return lc_mc_search;
173 }
174
175
176
177 void
178 mc_search_free (mc_search_t *lc_mc_search)
179 {
180 if (lc_mc_search == NULL)
181 return;
182
183 g_string_free (lc_mc_search->original.str, TRUE);
184 #ifdef HAVE_CHARSET
185 g_free (lc_mc_search->original.charset);
186 #endif
187 g_free (lc_mc_search->error_str);
188
189 if (lc_mc_search->prepared.conditions != NULL)
190 g_ptr_array_free (lc_mc_search->prepared.conditions, TRUE);
191
192 #ifdef SEARCH_TYPE_GLIB
193 if (lc_mc_search->regex_match_info != NULL)
194 g_match_info_free (lc_mc_search->regex_match_info);
195 #else
196 g_free (lc_mc_search->regex_match_info);
197 #endif
198
199 if (lc_mc_search->regex_buffer != NULL)
200 g_string_free (lc_mc_search->regex_buffer, TRUE);
201
202 g_free (lc_mc_search);
203 }
204
205
206
207 gboolean
208 mc_search_prepare (mc_search_t *lc_mc_search)
209 {
210 GPtrArray *ret;
211
212 if (lc_mc_search->prepared.conditions != NULL)
213 return lc_mc_search->prepared.result;
214
215 ret = g_ptr_array_new_with_free_func (mc_search__cond_struct_free);
216 #ifdef HAVE_CHARSET
217 if (!lc_mc_search->is_all_charsets)
218 g_ptr_array_add (ret,
219 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original.str,
220 lc_mc_search->original.charset));
221 else
222 {
223 gsize loop1;
224
225 for (loop1 = 0; loop1 < codepages->len; loop1++)
226 {
227 const char *id;
228
229 id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id;
230 if (g_ascii_strcasecmp (id, lc_mc_search->original.charset) == 0)
231 g_ptr_array_add (ret,
232 mc_search__cond_struct_new (lc_mc_search,
233 lc_mc_search->original.str,
234 lc_mc_search->original.charset));
235 else
236 {
237 GString *buffer;
238
239 buffer =
240 mc_search__recode_str (lc_mc_search->original.str->str,
241 lc_mc_search->original.str->len,
242 lc_mc_search->original.charset, id);
243 g_ptr_array_add (ret, mc_search__cond_struct_new (lc_mc_search, buffer, id));
244 g_string_free (buffer, TRUE);
245 }
246 }
247 }
248 #else
249 g_ptr_array_add (ret,
250 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original.str,
251 str_detect_termencoding ()));
252 #endif
253 lc_mc_search->prepared.conditions = ret;
254 lc_mc_search->prepared.result = (lc_mc_search->error == MC_SEARCH_E_OK);
255
256 return lc_mc_search->prepared.result;
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 gboolean
275 mc_search_run (mc_search_t *lc_mc_search, const void *user_data,
276 gsize start_search, gsize end_search, gsize *found_len)
277 {
278 gboolean ret = FALSE;
279
280 if (lc_mc_search == NULL || user_data == NULL)
281 return FALSE;
282 if (!mc_search_is_type_avail (lc_mc_search->search_type))
283 {
284 mc_search_set_error (lc_mc_search, MC_SEARCH_E_INPUT, "%s", _(STR_E_UNKNOWN_TYPE));
285 return FALSE;
286 }
287 #ifdef SEARCH_TYPE_GLIB
288 if (lc_mc_search->regex_match_info != NULL)
289 {
290 g_match_info_free (lc_mc_search->regex_match_info);
291 lc_mc_search->regex_match_info = NULL;
292 }
293 #endif
294
295 mc_search_set_error (lc_mc_search, MC_SEARCH_E_OK, NULL);
296
297 if (!mc_search_prepare (lc_mc_search))
298 return FALSE;
299
300 switch (lc_mc_search->search_type)
301 {
302 case MC_SEARCH_T_NORMAL:
303 ret = mc_search__run_normal (lc_mc_search, user_data, start_search, end_search, found_len);
304 break;
305 case MC_SEARCH_T_REGEX:
306 ret = mc_search__run_regex (lc_mc_search, user_data, start_search, end_search, found_len);
307 break;
308 case MC_SEARCH_T_GLOB:
309 ret = mc_search__run_glob (lc_mc_search, user_data, start_search, end_search, found_len);
310 break;
311 case MC_SEARCH_T_HEX:
312 ret = mc_search__run_hex (lc_mc_search, user_data, start_search, end_search, found_len);
313 break;
314 default:
315 break;
316 }
317 return ret;
318 }
319
320
321
322 gboolean
323 mc_search_is_type_avail (mc_search_type_t search_type)
324 {
325 switch (search_type)
326 {
327 case MC_SEARCH_T_GLOB:
328 case MC_SEARCH_T_NORMAL:
329 case MC_SEARCH_T_REGEX:
330 case MC_SEARCH_T_HEX:
331 return TRUE;
332 default:
333 break;
334 }
335 return FALSE;
336 }
337
338
339
340 const mc_search_type_str_t *
341 mc_search_types_list_get (size_t *num)
342 {
343
344 if (num != NULL)
345 *num = G_N_ELEMENTS (mc_search__list_types) - 1;
346
347 return mc_search__list_types;
348 }
349
350
351
352 GString *
353 mc_search_prepare_replace_str (mc_search_t *lc_mc_search, GString *replace_str)
354 {
355 GString *ret;
356
357 if (replace_str == NULL || replace_str->len == 0)
358 return g_string_new ("");
359
360 if (lc_mc_search == NULL)
361 return mc_g_string_dup (replace_str);
362
363 switch (lc_mc_search->search_type)
364 {
365 case MC_SEARCH_T_REGEX:
366 ret = mc_search_regex_prepare_replace_str (lc_mc_search, replace_str);
367 break;
368 case MC_SEARCH_T_GLOB:
369 ret = mc_search_glob_prepare_replace_str (lc_mc_search, replace_str);
370 break;
371 case MC_SEARCH_T_NORMAL:
372 ret = mc_search_normal_prepare_replace_str (lc_mc_search, replace_str);
373 break;
374 case MC_SEARCH_T_HEX:
375 ret = mc_search_hex_prepare_replace_str (lc_mc_search, replace_str);
376 break;
377 default:
378 ret = mc_g_string_dup (replace_str);
379 break;
380 }
381 return ret;
382 }
383
384
385
386 char *
387 mc_search_prepare_replace_str2 (mc_search_t *lc_mc_search, const char *replace_str)
388 {
389 GString *ret;
390 GString *replace_str2;
391
392 replace_str2 = g_string_new (replace_str);
393 ret = mc_search_prepare_replace_str (lc_mc_search, replace_str2);
394 g_string_free (replace_str2, TRUE);
395 return (ret != NULL) ? g_string_free (ret, FALSE) : NULL;
396 }
397
398
399
400 gboolean
401 mc_search_is_fixed_search_str (const mc_search_t *lc_mc_search)
402 {
403 if (lc_mc_search == NULL)
404 return FALSE;
405 switch (lc_mc_search->search_type)
406 {
407 case MC_SEARCH_T_REGEX:
408 case MC_SEARCH_T_GLOB:
409 return FALSE;
410 default:
411 return TRUE;
412 }
413 }
414
415
416
417
418
419
420
421
422
423
424
425
426 gboolean
427 mc_search (const gchar *pattern, const gchar *pattern_charset, const gchar *str,
428 mc_search_type_t type)
429 {
430 gboolean ret;
431 mc_search_t *search;
432
433 if (str == NULL)
434 return FALSE;
435
436 search = mc_search_new (pattern, pattern_charset);
437 if (search == NULL)
438 return FALSE;
439
440 search->search_type = type;
441 search->is_case_sensitive = TRUE;
442
443 if (type == MC_SEARCH_T_GLOB)
444 search->is_entire_line = TRUE;
445
446 ret = mc_search_run (search, str, 0, strlen (str), NULL);
447 mc_search_free (search);
448 return ret;
449 }
450
451
452
453 int
454 mc_search_getstart_result_by_num (mc_search_t *lc_mc_search, int lc_index)
455 {
456 if (lc_mc_search == NULL)
457 return 0;
458 if (lc_mc_search->search_type == MC_SEARCH_T_NORMAL)
459 return 0;
460 #ifdef SEARCH_TYPE_GLIB
461 {
462 gint start_pos;
463 gint end_pos;
464
465 g_match_info_fetch_pos (lc_mc_search->regex_match_info, lc_index, &start_pos, &end_pos);
466 return (int) start_pos;
467 }
468 #else
469 return lc_mc_search->iovector[lc_index * 2];
470 #endif
471 }
472
473
474
475 int
476 mc_search_getend_result_by_num (mc_search_t *lc_mc_search, int lc_index)
477 {
478 if (lc_mc_search == NULL)
479 return 0;
480 if (lc_mc_search->search_type == MC_SEARCH_T_NORMAL)
481 return 0;
482 #ifdef SEARCH_TYPE_GLIB
483 {
484 gint start_pos;
485 gint end_pos;
486
487 g_match_info_fetch_pos (lc_mc_search->regex_match_info, lc_index, &start_pos, &end_pos);
488 return (int) end_pos;
489 }
490 #else
491 return lc_mc_search->iovector[lc_index * 2 + 1];
492 #endif
493 }
494
495
496
497
498
499
500
501
502
503
504 void
505 mc_search_set_error (mc_search_t *lc_mc_search, mc_search_error_t code, const gchar *format, ...)
506 {
507 lc_mc_search->error = code;
508
509 MC_PTR_FREE (lc_mc_search->error_str);
510
511 if (format != NULL)
512 {
513 va_list args;
514
515 va_start (args, format);
516 lc_mc_search->error_str = g_strdup_vprintf (format, args);
517 va_end (args);
518 }
519 }
520
521