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)
98 g_string_free (mc_search_cond->upper, TRUE);
99
100 if (mc_search_cond->lower)
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)
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->conditions != NULL)
192 mc_search__conditions_free (lc_mc_search->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 ret = g_ptr_array_new ();
215 #ifdef HAVE_CHARSET
216 if (lc_mc_search->is_all_charsets)
217 {
218 gsize loop1;
219
220 for (loop1 = 0; loop1 < codepages->len; loop1++)
221 {
222 const char *id;
223 gsize recoded_str_len;
224 gchar *buffer;
225
226 id = ((codepage_desc *) g_ptr_array_index (codepages, loop1))->id;
227 if (g_ascii_strcasecmp (id, lc_mc_search->original_charset) == 0)
228 {
229 g_ptr_array_add (ret,
230 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original,
231 lc_mc_search->original_len,
232 lc_mc_search->original_charset));
233 continue;
234 }
235
236 buffer =
237 mc_search__recode_str (lc_mc_search->original, lc_mc_search->original_len,
238 lc_mc_search->original_charset, id, &recoded_str_len);
239
240 g_ptr_array_add (ret,
241 mc_search__cond_struct_new (lc_mc_search, buffer,
242 recoded_str_len, id));
243 g_free (buffer);
244 }
245 }
246 else
247 {
248 g_ptr_array_add (ret,
249 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original,
250 lc_mc_search->original_len,
251 lc_mc_search->original_charset));
252 }
253 #else
254 g_ptr_array_add (ret,
255 mc_search__cond_struct_new (lc_mc_search, lc_mc_search->original,
256 lc_mc_search->original_len,
257 str_detect_termencoding ()));
258 #endif
259 lc_mc_search->conditions = ret;
260
261 return (lc_mc_search->error == MC_SEARCH_E_OK);
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 gboolean
280 mc_search_run (mc_search_t * lc_mc_search, const void *user_data,
281 gsize start_search, gsize end_search, gsize * found_len)
282 {
283 gboolean ret = FALSE;
284
285 if (lc_mc_search == NULL || user_data == NULL)
286 return FALSE;
287 if (!mc_search_is_type_avail (lc_mc_search->search_type))
288 {
289 mc_search_set_error (lc_mc_search, MC_SEARCH_E_INPUT, "%s", _(STR_E_UNKNOWN_TYPE));
290 return FALSE;
291 }
292 #ifdef SEARCH_TYPE_GLIB
293 if (lc_mc_search->regex_match_info != NULL)
294 {
295 g_match_info_free (lc_mc_search->regex_match_info);
296 lc_mc_search->regex_match_info = NULL;
297 }
298 #endif
299
300 mc_search_set_error (lc_mc_search, MC_SEARCH_E_OK, NULL);
301
302 if ((lc_mc_search->conditions == NULL) && !mc_search_prepare (lc_mc_search))
303 return FALSE;
304
305 switch (lc_mc_search->search_type)
306 {
307 case MC_SEARCH_T_NORMAL:
308 ret = mc_search__run_normal (lc_mc_search, user_data, start_search, end_search, found_len);
309 break;
310 case MC_SEARCH_T_REGEX:
311 ret = mc_search__run_regex (lc_mc_search, user_data, start_search, end_search, found_len);
312 break;
313 case MC_SEARCH_T_GLOB:
314 ret = mc_search__run_glob (lc_mc_search, user_data, start_search, end_search, found_len);
315 break;
316 case MC_SEARCH_T_HEX:
317 ret = mc_search__run_hex (lc_mc_search, user_data, start_search, end_search, found_len);
318 break;
319 default:
320 break;
321 }
322 return ret;
323 }
324
325
326
327 gboolean
328 mc_search_is_type_avail (mc_search_type_t search_type)
329 {
330 switch (search_type)
331 {
332 case MC_SEARCH_T_GLOB:
333 case MC_SEARCH_T_NORMAL:
334 case MC_SEARCH_T_REGEX:
335 case MC_SEARCH_T_HEX:
336 return TRUE;
337 default:
338 break;
339 }
340 return FALSE;
341 }
342
343
344
345 const mc_search_type_str_t *
346 mc_search_types_list_get (size_t * num)
347 {
348
349 if (num != NULL)
350 *num = G_N_ELEMENTS (mc_search__list_types) - 1;
351
352 return mc_search__list_types;
353 }
354
355
356
357 GString *
358 mc_search_prepare_replace_str (mc_search_t * lc_mc_search, GString * replace_str)
359 {
360 GString *ret;
361
362 if (replace_str == NULL || replace_str->len == 0)
363 return g_string_new ("");
364
365 if (lc_mc_search == NULL)
366 return g_string_new_len (replace_str->str, replace_str->len);
367
368 switch (lc_mc_search->search_type)
369 {
370 case MC_SEARCH_T_REGEX:
371 ret = mc_search_regex_prepare_replace_str (lc_mc_search, replace_str);
372 break;
373 case MC_SEARCH_T_GLOB:
374 ret = mc_search_glob_prepare_replace_str (lc_mc_search, replace_str);
375 break;
376 case MC_SEARCH_T_NORMAL:
377 ret = mc_search_normal_prepare_replace_str (lc_mc_search, replace_str);
378 break;
379 case MC_SEARCH_T_HEX:
380 ret = mc_search_hex_prepare_replace_str (lc_mc_search, replace_str);
381 break;
382 default:
383 ret = g_string_new_len (replace_str->str, replace_str->len);
384 break;
385 }
386 return ret;
387 }
388
389
390
391 char *
392 mc_search_prepare_replace_str2 (mc_search_t * lc_mc_search, const char *replace_str)
393 {
394 GString *ret;
395 GString *replace_str2;
396
397 replace_str2 = g_string_new (replace_str);
398 ret = mc_search_prepare_replace_str (lc_mc_search, replace_str2);
399 g_string_free (replace_str2, TRUE);
400 return (ret != NULL) ? g_string_free (ret, FALSE) : NULL;
401 }
402
403
404
405 gboolean
406 mc_search_is_fixed_search_str (mc_search_t * lc_mc_search)
407 {
408 if (lc_mc_search == NULL)
409 return FALSE;
410 switch (lc_mc_search->search_type)
411 {
412 case MC_SEARCH_T_REGEX:
413 case MC_SEARCH_T_GLOB:
414 return FALSE;
415 default:
416 return TRUE;
417 }
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431 gboolean
432 mc_search (const gchar * pattern, const gchar * pattern_charset, const gchar * str,
433 mc_search_type_t type)
434 {
435 gboolean ret;
436 mc_search_t *search;
437
438 if (str == NULL)
439 return FALSE;
440
441 search = mc_search_new (pattern, pattern_charset);
442 if (search == NULL)
443 return FALSE;
444
445 search->search_type = type;
446 search->is_case_sensitive = TRUE;
447
448 if (type == MC_SEARCH_T_GLOB)
449 search->is_entire_line = TRUE;
450
451 ret = mc_search_run (search, str, 0, strlen (str), NULL);
452 mc_search_free (search);
453 return ret;
454 }
455
456
457
458 int
459 mc_search_getstart_result_by_num (mc_search_t * lc_mc_search, int lc_index)
460 {
461 if (lc_mc_search == NULL)
462 return 0;
463 if (lc_mc_search->search_type == MC_SEARCH_T_NORMAL)
464 return 0;
465 #ifdef SEARCH_TYPE_GLIB
466 {
467 gint start_pos;
468 gint end_pos;
469
470 g_match_info_fetch_pos (lc_mc_search->regex_match_info, lc_index, &start_pos, &end_pos);
471 return (int) start_pos;
472 }
473 #else
474 return lc_mc_search->iovector[lc_index * 2];
475 #endif
476 }
477
478
479
480 int
481 mc_search_getend_result_by_num (mc_search_t * lc_mc_search, int lc_index)
482 {
483 if (lc_mc_search == NULL)
484 return 0;
485 if (lc_mc_search->search_type == MC_SEARCH_T_NORMAL)
486 return 0;
487 #ifdef SEARCH_TYPE_GLIB
488 {
489 gint start_pos;
490 gint end_pos;
491
492 g_match_info_fetch_pos (lc_mc_search->regex_match_info, lc_index, &start_pos, &end_pos);
493 return (int) end_pos;
494 }
495 #else
496 return lc_mc_search->iovector[lc_index * 2 + 1];
497 #endif
498 }
499
500
501
502
503
504
505
506
507
508
509 void
510 mc_search_set_error (mc_search_t * lc_mc_search, mc_search_error_t code, const gchar * format, ...)
511 {
512 lc_mc_search->error = code;
513
514 MC_PTR_FREE (lc_mc_search->error_str);
515
516 if (format != NULL)
517 {
518 va_list args;
519
520 va_start (args, format);
521 lc_mc_search->error_str = g_strdup_vprintf (format, args);
522 va_end (args);
523 }
524 }
525
526