This source file includes following definitions.
- str_escape
- str_unescape
- str_shell_escape
- str_glob_escape
- str_regex_escape
- str_shell_unescape
- str_glob_unescape
- str_regex_unescape
- str_is_char_escaped
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 #include <config.h>
28
29 #include "lib/global.h"
30 #include "lib/strutil.h"
31
32
33
34
35
36
37
38
39
40
41
42 static const char ESCAPE_SHELL_CHARS[] = " !#$%()&{}[]`?|<>;*\\\"'";
43 static const char ESCAPE_REGEX_CHARS[] = "^!#$%()&{}[]`?|<>;*+.\\";
44 static const char ESCAPE_GLOB_CHARS[] = "$*\\?";
45
46
47
48
49
50
51
52
53
54 char *
55 str_escape (const char *src, gsize src_len, const char *escaped_chars,
56 gboolean escape_non_printable)
57 {
58 GString *ret;
59 gsize curr_index;
60
61 if (src == NULL)
62 return NULL;
63
64 if (*src == '\0')
65 return strdup ("");
66
67 ret = g_string_new ("");
68
69 if (src_len == (gsize) (-1))
70 src_len = strlen (src);
71
72 for (curr_index = 0; curr_index < src_len; curr_index++)
73 {
74 if (escape_non_printable)
75 {
76 switch (src[curr_index])
77 {
78 case '\n':
79 g_string_append (ret, "\\n");
80 continue;
81 case '\t':
82 g_string_append (ret, "\\t");
83 continue;
84 case '\b':
85 g_string_append (ret, "\\b");
86 continue;
87 case '\0':
88 g_string_append (ret, "\\0");
89 continue;
90 default:
91 break;
92 }
93 }
94
95 if (strchr (escaped_chars, (int) src[curr_index]))
96 g_string_append_c (ret, '\\');
97
98 g_string_append_c (ret, src[curr_index]);
99 }
100 return g_string_free (ret, FALSE);
101 }
102
103
104
105 char *
106 str_unescape (const char *src, gsize src_len, const char *unescaped_chars,
107 gboolean unescape_non_printable)
108 {
109 GString *ret;
110 gsize curr_index;
111
112 if (src == NULL)
113 return NULL;
114
115 if (*src == '\0')
116 return strdup ("");
117
118 ret = g_string_sized_new (16);
119
120 if (src_len == (gsize) (-1))
121 src_len = strlen (src);
122 src_len--;
123
124 for (curr_index = 0; curr_index < src_len; curr_index++)
125 {
126 if (src[curr_index] != '\\')
127 {
128 g_string_append_c (ret, src[curr_index]);
129 continue;
130 }
131
132 curr_index++;
133
134 if (unescaped_chars == ESCAPE_SHELL_CHARS && src[curr_index] == '$')
135 {
136
137 g_string_append_c (ret, '\\');
138 }
139 else
140 {
141 if (unescape_non_printable)
142 {
143 switch (src[curr_index])
144 {
145 case 'n':
146 g_string_append_c (ret, '\n');
147 continue;
148 case 't':
149 g_string_append_c (ret, '\t');
150 continue;
151 case 'b':
152 g_string_append_c (ret, '\b');
153 continue;
154 case '0':
155 g_string_append_c (ret, '\0');
156 continue;
157 default:
158 break;
159 }
160 }
161
162 if (strchr (unescaped_chars, (int) src[curr_index]) == NULL)
163 g_string_append_c (ret, '\\');
164 }
165
166 g_string_append_c (ret, src[curr_index]);
167 }
168 g_string_append_c (ret, src[curr_index]);
169
170 return g_string_free (ret, FALSE);
171 }
172
173
174
175
176
177
178
179
180
181
182
183
184 char *
185 str_shell_escape (const char *src)
186 {
187 return str_escape (src, -1, ESCAPE_SHELL_CHARS, FALSE);
188 }
189
190
191
192 char *
193 str_glob_escape (const char *src)
194 {
195 return str_escape (src, -1, ESCAPE_GLOB_CHARS, TRUE);
196 }
197
198
199
200 char *
201 str_regex_escape (const char *src)
202 {
203 return str_escape (src, -1, ESCAPE_REGEX_CHARS, TRUE);
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217 char *
218 str_shell_unescape (const char *text)
219 {
220 return str_unescape (text, -1, ESCAPE_SHELL_CHARS, TRUE);
221 }
222
223
224
225 char *
226 str_glob_unescape (const char *text)
227 {
228 return str_unescape (text, -1, ESCAPE_GLOB_CHARS, TRUE);
229 }
230
231
232 char *
233 str_regex_unescape (const char *text)
234 {
235 return str_unescape (text, -1, ESCAPE_REGEX_CHARS, TRUE);
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249 gboolean
250 str_is_char_escaped (const char *start, const char *current)
251 {
252 int num_esc = 0;
253
254 if (start == NULL || current == NULL || current <= start)
255 return FALSE;
256
257 current--;
258 while (current >= start && *current == '\\')
259 {
260 num_esc++;
261 current--;
262 }
263 return (gboolean) num_esc % 2;
264 }
265
266