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