1 | /* |
---|
2 | Search text engine. |
---|
3 | HEX-style pattern matching |
---|
4 | |
---|
5 | Copyright (C) 2009-2016 |
---|
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 <stdio.h> |
---|
30 | |
---|
31 | #include "lib/global.h" |
---|
32 | #include "lib/strutil.h" |
---|
33 | #include "lib/search.h" |
---|
34 | #include "lib/strescape.h" |
---|
35 | |
---|
36 | #include "internal.h" |
---|
37 | |
---|
38 | /*** global variables ****************************************************************************/ |
---|
39 | |
---|
40 | /*** file scope macro definitions ****************************************************************/ |
---|
41 | |
---|
42 | /*** file scope type declarations ****************************************************************/ |
---|
43 | |
---|
44 | /*** file scope variables ************************************************************************/ |
---|
45 | |
---|
46 | /*** file scope functions ************************************************************************/ |
---|
47 | |
---|
48 | static GString * |
---|
49 | mc_search__hex_translate_to_regex (const GString * astr) |
---|
50 | { |
---|
51 | GString *buff; |
---|
52 | gchar *tmp_str, *tmp_str2; |
---|
53 | gsize tmp_str_len; |
---|
54 | gsize loop = 0; |
---|
55 | |
---|
56 | buff = g_string_sized_new (64); |
---|
57 | tmp_str = g_strndup (astr->str, astr->len); |
---|
58 | tmp_str2 = tmp_str; |
---|
59 | |
---|
60 | /* remove 0x prefices */ |
---|
61 | while (TRUE) |
---|
62 | { |
---|
63 | tmp_str2 = strstr (tmp_str2, "0x"); |
---|
64 | if (tmp_str2 == NULL) |
---|
65 | break; |
---|
66 | |
---|
67 | *tmp_str2++ = ' '; |
---|
68 | *tmp_str2++ = ' '; |
---|
69 | } |
---|
70 | |
---|
71 | g_strchug (tmp_str); /* trim leadind whitespaces */ |
---|
72 | tmp_str_len = strlen (tmp_str); |
---|
73 | |
---|
74 | while (loop < tmp_str_len) |
---|
75 | { |
---|
76 | unsigned int val; |
---|
77 | int ptr; |
---|
78 | |
---|
79 | /* cppcheck-suppress invalidscanf */ |
---|
80 | if (sscanf (tmp_str + loop, "%x%n", &val, &ptr)) |
---|
81 | { |
---|
82 | if (val > 255) |
---|
83 | loop++; |
---|
84 | else |
---|
85 | { |
---|
86 | g_string_append_printf (buff, "\\x%02X", (unsigned char) val); |
---|
87 | loop += ptr; |
---|
88 | } |
---|
89 | } |
---|
90 | else if (*(tmp_str + loop) == '"') |
---|
91 | { |
---|
92 | gsize loop2 = 0; |
---|
93 | |
---|
94 | loop++; |
---|
95 | while (loop + loop2 < tmp_str_len) |
---|
96 | { |
---|
97 | if (*(tmp_str + loop + loop2) == '"' && |
---|
98 | !strutils_is_char_escaped (tmp_str, tmp_str + loop + loop2)) |
---|
99 | break; |
---|
100 | loop2++; |
---|
101 | } |
---|
102 | |
---|
103 | // g_string_append_len (buff, tmp_str + loop, loop2 - 1); |
---|
104 | // loop += loop2; |
---|
105 | g_string_append_len (buff, tmp_str + loop, loop2); |
---|
106 | loop += loop2 + 1; |
---|
107 | } |
---|
108 | else |
---|
109 | loop++; |
---|
110 | } |
---|
111 | |
---|
112 | g_free (tmp_str); |
---|
113 | |
---|
114 | return buff; |
---|
115 | } |
---|
116 | |
---|
117 | /*** public functions ****************************************************************************/ |
---|
118 | |
---|
119 | void |
---|
120 | mc_search__cond_struct_new_init_hex (const char *charset, mc_search_t * lc_mc_search, |
---|
121 | mc_search_cond_t * mc_search_cond) |
---|
122 | { |
---|
123 | GString *tmp; |
---|
124 | |
---|
125 | g_string_ascii_down (mc_search_cond->str); |
---|
126 | tmp = mc_search__hex_translate_to_regex (mc_search_cond->str); |
---|
127 | g_string_free (mc_search_cond->str, TRUE); |
---|
128 | mc_search_cond->str = tmp; |
---|
129 | lc_mc_search->is_case_sensitive = TRUE; // always case-sensitive here |
---|
130 | |
---|
131 | mc_search__cond_struct_new_init_regex (charset, lc_mc_search, mc_search_cond); |
---|
132 | } |
---|
133 | |
---|
134 | /* --------------------------------------------------------------------------------------------- */ |
---|
135 | |
---|
136 | gboolean |
---|
137 | mc_search__run_hex (mc_search_t * lc_mc_search, const void *user_data, |
---|
138 | gsize start_search, gsize end_search, gsize * found_len) |
---|
139 | { |
---|
140 | return mc_search__run_regex (lc_mc_search, user_data, start_search, end_search, found_len); |
---|
141 | } |
---|
142 | |
---|
143 | /* --------------------------------------------------------------------------------------------- */ |
---|
144 | |
---|
145 | GString * |
---|
146 | mc_search_hex_prepare_replace_str (mc_search_t * lc_mc_search, GString * replace_str) |
---|
147 | { |
---|
148 | (void) lc_mc_search; |
---|
149 | return g_string_new_len (replace_str->str, replace_str->len); |
---|
150 | } |
---|
151 | |
---|
152 | /* --------------------------------------------------------------------------------------------- */ |
---|