2 Functions for escaping and unescaping strings
4 Copyright (C) 2009 The Free Software Foundation, Inc.
7 Slava Zanko <slavazanko@gmail.com>, 2009;
8 Patrick Winnertz <winnie@debian.org>, 2009
10 This file is part of the Midnight Commander.
12 The Midnight Commander is free software; you can redistribute it
13 and/or modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 The Midnight Commander is distributed in the hope that it will be
18 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
19 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
29 #include "../src/strescape.h"
32 /*** global variables ****************************************************************************/
34 /*** file scope macro definitions ****************************************************************/
36 /*** file scope type declarations ****************************************************************/
38 /*** file scope variables ************************************************************************/
40 static const char ESCAPE_SHELL_CHARS
[] = " !#$%()&{}[]`?|<>;*\\\"'";
41 static const char ESCAPE_REGEX_CHARS
[] = "^!#$%()&{}[]`?|<>;*.\\";
42 static const char ESCAPE_GLOB_CHARS
[] = "$*\\";
44 /*** file scope functions ************************************************************************/
46 /*** public functions ****************************************************************************/
49 strutils_escape (const char *src
, gsize src_len
, const char *escaped_chars
,
50 gboolean escape_non_printable
)
54 /* do NOT break allocation semantics */
61 ret
= g_string_new ("");
63 if (src_len
== (gsize
)-1)
64 src_len
= strlen (src
);
66 for (curr_index
= 0; curr_index
< src_len
; curr_index
++) {
68 if (escape_non_printable
) {
69 switch (src
[curr_index
]) {
71 g_string_append (ret
, "\\n");
75 g_string_append (ret
, "\\t");
79 g_string_append (ret
, "\\b");
83 g_string_append (ret
, "\\0");
89 if (strchr (escaped_chars
, (int) src
[curr_index
]))
90 g_string_append_c (ret
, '\\');
92 g_string_append_c (ret
, src
[curr_index
]);
94 return g_string_free (ret
, FALSE
);
97 /* --------------------------------------------------------------------------------------------- */
99 strutils_unescape (const char *src
, gsize src_len
, const char *unescaped_chars
,
100 gboolean unescape_non_printable
)
111 ret
= g_string_new ("");
113 if (src_len
== (gsize
)-1)
114 src_len
= strlen (src
);
116 for (curr_index
= 0; curr_index
< src_len
-1; curr_index
++) {
117 if (src
[curr_index
] != '\\'){
118 g_string_append_c (ret
, src
[curr_index
]);
122 if (unescape_non_printable
) {
123 switch (src
[curr_index
]) {
125 g_string_append_c (ret
, '\n');
129 g_string_append_c (ret
, '\t');
133 g_string_append_c (ret
, '\b');
137 g_string_append (ret
, '\0');
142 if (strchr (unescaped_chars
, (int) src
[curr_index
]) == NULL
)
143 g_string_append_c (ret
, '\\');
145 g_string_append_c (ret
, src
[curr_index
]);
147 g_string_append_c (ret
, src
[curr_index
]);
149 return g_string_free (ret
, FALSE
);
151 /* --------------------------------------------------------------------------------------------- */
153 /** To be compatible with the general posix command lines we have to escape
154 strings for the command line
160 return escaped string (which needs to be freed later)
161 or NULL when NULL string is passed.
164 strutils_shell_escape (const char *src
)
166 return strutils_escape (src
, -1, ESCAPE_SHELL_CHARS
, FALSE
);
169 /* --------------------------------------------------------------------------------------------- */
172 strutils_glob_escape (const char *src
)
174 return strutils_escape (src
, -1, ESCAPE_GLOB_CHARS
, TRUE
);
177 /* --------------------------------------------------------------------------------------------- */
180 strutils_regex_escape (const char *src
)
182 return strutils_escape (src
, -1, ESCAPE_REGEX_CHARS
, TRUE
);
185 /* --------------------------------------------------------------------------------------------- */
187 /** Unescape paths or other strings for e.g the internal cd
188 shell-unescape within a given buffer (writing to it!)
191 string for unescaping
194 return unescaped string (which needs to be freed)
197 strutils_shell_unescape (const char *text
)
199 return strutils_unescape (text
, -1, ESCAPE_SHELL_CHARS
, TRUE
);
202 /* --------------------------------------------------------------------------------------------- */
205 strutils_glob_unescape (const char *text
)
207 return strutils_unescape (text
, -1, ESCAPE_GLOB_CHARS
, TRUE
);
210 /* --------------------------------------------------------------------------------------------- */
212 strutils_regex_unescape (const char *text
)
214 return strutils_unescape (text
, -1, ESCAPE_REGEX_CHARS
, TRUE
);
217 /* --------------------------------------------------------------------------------------------- */
219 /** Check if char in pointer contain escape'd chars
225 pointer to checked character
228 return TRUE if string contain escaped chars
229 otherwise return FALSE
232 strutils_is_char_escaped (const char *start
, const char *current
)
236 if (start
== NULL
|| current
== NULL
|| current
<= start
)
240 while (current
>= start
&& *current
== '\\') {
244 return (gboolean
) num_esc
% 2;
248 /* --------------------------------------------------------------------------------------------- */