mirror of
https://github.com/MidnightCommander/mc
synced 2025-03-11 18:32:53 +03:00
Moved 'escape' and 'unescape' strings functions from src/util.[ch] into src/strescape.[ch]
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
5834a9ed84
commit
5f810602e0
@ -67,7 +67,7 @@ SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \
|
||||
widget.h win.c win.h wtools.c wtools.h unixcompat.h \
|
||||
x11conn.h x11conn.c ecs.h ecs.c \
|
||||
strutil.h strutil.c strutilascii.c strutil8bit.c strutilutf8.c \
|
||||
search/search.h
|
||||
search/search.h strescape.c strescape.h
|
||||
|
||||
if CHARSET
|
||||
mc_SOURCES = $(SRCS) $(CHARSET_SRC)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "tree.h" /* for tree_chdir */
|
||||
#include "color.h" /* DEFAULT_COLOR */
|
||||
#include "execute.h" /* shell_execute */
|
||||
#include "../src/strescape.h"
|
||||
|
||||
/* This holds the command line */
|
||||
WInput *cmdline;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "wtools.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
#include "../src/strescape.h"
|
||||
#include "key.h" /* XCTRL and ALT macros */
|
||||
#include "strutil.h"
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
#include "widget.h"
|
||||
#include "wtools.h"
|
||||
#include "background.h" /* we_are_background */
|
||||
/* #include "util.h" */
|
||||
#include "../src/strescape.h"
|
||||
#include "strutil.h"
|
||||
#include "../src/search/search.h"
|
||||
|
||||
|
207
src/strescape.c
Normal file
207
src/strescape.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
Functions for escaping and unescaping strings
|
||||
|
||||
Copyright (C) 2009 The Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
Slava Zanko <slavazanko@gmail.com>, 2009;
|
||||
Patrick Winnertz <winnie@debian.org>, 2009
|
||||
|
||||
This file is part of the Midnight Commander.
|
||||
|
||||
The Midnight Commander is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Midnight Commander is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "../src/strescape.h"
|
||||
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
#define shell_escape_toesc(x) \
|
||||
(((x)==' ')||((x)=='!')||((x)=='#')||((x)=='$')||((x)=='%')|| \
|
||||
((x)=='(')||((x)==')')||((x)=='\'')||((x)=='&')||((x)=='~')|| \
|
||||
((x)=='{')||((x)=='}')||((x)=='[')||((x)==']')||((x)=='`')|| \
|
||||
((x)=='?')||((x)=='|')||((x)=='<')||((x)=='>')||((x)==';')|| \
|
||||
((x)=='*')||((x)=='\\')||((x)=='"'))
|
||||
|
||||
#define shell_escape_nottoesc(x) \
|
||||
(((x)!=0) && (!shell_escape_toesc((x))))
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
|
||||
/*** public functions ****************************************************************************/
|
||||
|
||||
/** To be compatible with the general posix command lines we have to escape
|
||||
strings for the command line
|
||||
|
||||
\params in
|
||||
string for escaping
|
||||
|
||||
\returns
|
||||
return escaped string (which needs to be freed later)
|
||||
or NULL when NULL string is passed.
|
||||
*/
|
||||
char*
|
||||
shell_escape(const char* src)
|
||||
{
|
||||
GString *str;
|
||||
char *result = NULL;
|
||||
|
||||
/* do NOT break allocation semantics */
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
if (*src == '\0')
|
||||
return strdup("");
|
||||
|
||||
str = g_string_new("");
|
||||
|
||||
/* look for the first char to escape */
|
||||
while (1)
|
||||
{
|
||||
char c;
|
||||
/* copy over all chars not to escape */
|
||||
while ((c=(*src)) && shell_escape_nottoesc(c))
|
||||
{
|
||||
g_string_append_c(str,c);
|
||||
src++;
|
||||
}
|
||||
|
||||
/* at this point we either have an \0 or an char to escape */
|
||||
if (!c) {
|
||||
result = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
g_string_append_c(str,'\\');
|
||||
g_string_append_c(str,c);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** Unescape paths or other strings for e.g the internal cd
|
||||
shell-unescape within a given buffer (writing to it!)
|
||||
|
||||
\params src
|
||||
string for unescaping
|
||||
|
||||
\returns
|
||||
return unescaped string (which needs to be freed)
|
||||
*/
|
||||
char*
|
||||
shell_unescape(const char* text)
|
||||
{
|
||||
GString *str;
|
||||
char *result = NULL;
|
||||
const char* readptr;
|
||||
char c;
|
||||
|
||||
if (!text)
|
||||
return NULL;
|
||||
|
||||
|
||||
/* look for the first \ - that's quick skipover if there's nothing to escape */
|
||||
readptr = text;
|
||||
while ((*readptr) && ((*readptr)!='\\')) readptr++;
|
||||
if (!(*readptr)) {
|
||||
result = g_strdup(text);
|
||||
return result;
|
||||
}
|
||||
str = g_string_new_len(text, readptr - text);
|
||||
|
||||
/* if we're here, we're standing on the first '\' */
|
||||
while ((c = *readptr))
|
||||
{
|
||||
if (c=='\\')
|
||||
{
|
||||
readptr++;
|
||||
switch ((c = *readptr))
|
||||
{
|
||||
case '\0': /* end of string! malformed escape string */
|
||||
goto out;
|
||||
|
||||
case 'n': g_string_append_c(str,'\n'); break;
|
||||
case 'r': g_string_append_c(str,'\r'); break;
|
||||
case 't': g_string_append_c(str,'\t'); break;
|
||||
|
||||
case ' ':
|
||||
case '\\':
|
||||
case '#':
|
||||
case '$':
|
||||
case '%':
|
||||
case '(':
|
||||
case ')':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}':
|
||||
case '<':
|
||||
case '>':
|
||||
case '!':
|
||||
case '*':
|
||||
case '?':
|
||||
case '~':
|
||||
case '`':
|
||||
case '"':
|
||||
case ';':
|
||||
default:
|
||||
g_string_append_c(str,c); break;
|
||||
}
|
||||
}
|
||||
else /* got a normal character */
|
||||
{
|
||||
g_string_append_c(str,c);
|
||||
}
|
||||
readptr++;
|
||||
}
|
||||
out:
|
||||
|
||||
result = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return result;
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** Check if char in pointer contain escape'd chars
|
||||
|
||||
\params in
|
||||
string for checking
|
||||
|
||||
\returns
|
||||
return TRUE if string contain escaped chars
|
||||
otherwise return FALSE
|
||||
*/
|
||||
gboolean
|
||||
shell_is_char_escaped ( const char *in )
|
||||
{
|
||||
if (in == NULL || !*in || in[0] != '\\')
|
||||
return FALSE;
|
||||
if (shell_escape_toesc(in[1]))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
22
src/strescape.h
Normal file
22
src/strescape.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef MC__STRUTILS_ESCAPE_H
|
||||
#define MC__STRUTILS_ESCAPE_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "../src/global.h" /* <glib.h> */
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
gboolean shell_is_char_escaped ( const char * );
|
||||
char *shell_unescape( const char * );
|
||||
char *shell_escape( const char * );
|
||||
|
||||
#endif
|
160
src/util.c
160
src/util.c
@ -1420,163 +1420,3 @@ Q_ (const char *s)
|
||||
return (sep != NULL) ? sep + 1 : result;
|
||||
}
|
||||
|
||||
#define shell_escape_toesc(x) \
|
||||
(((x)==' ')||((x)=='!')||((x)=='#')||((x)=='$')||((x)=='%')|| \
|
||||
((x)=='(')||((x)==')')||((x)=='\'')||((x)=='&')||((x)=='~')|| \
|
||||
((x)=='{')||((x)=='}')||((x)=='[')||((x)==']')||((x)=='`')|| \
|
||||
((x)=='?')||((x)=='|')||((x)=='<')||((x)=='>')||((x)==';')|| \
|
||||
((x)=='*')||((x)=='\\')||((x)=='"'))
|
||||
|
||||
#define shell_escape_nottoesc(x) \
|
||||
(((x)!=0) && (!shell_escape_toesc((x))))
|
||||
|
||||
/** To be compatible with the general posix command lines we have to escape
|
||||
strings for the command line
|
||||
|
||||
\params in
|
||||
string for escaping
|
||||
|
||||
\returns
|
||||
return escaped string (which needs to be freed later)
|
||||
or NULL when NULL string is passed.
|
||||
*/
|
||||
char*
|
||||
shell_escape(const char* src)
|
||||
{
|
||||
GString *str;
|
||||
char *result = NULL;
|
||||
|
||||
/* do NOT break allocation semantics */
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
if (*src == '\0')
|
||||
return strdup("");
|
||||
|
||||
str = g_string_new("");
|
||||
|
||||
/* look for the first char to escape */
|
||||
while (1)
|
||||
{
|
||||
char c;
|
||||
/* copy over all chars not to escape */
|
||||
while ((c=(*src)) && shell_escape_nottoesc(c))
|
||||
{
|
||||
g_string_append_c(str,c);
|
||||
src++;
|
||||
}
|
||||
|
||||
/* at this point we either have an \0 or an char to escape */
|
||||
if (!c) {
|
||||
result = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
g_string_append_c(str,'\\');
|
||||
g_string_append_c(str,c);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Unescape paths or other strings for e.g the internal cd
|
||||
shell-unescape within a given buffer (writing to it!)
|
||||
|
||||
\params src
|
||||
string for unescaping
|
||||
|
||||
\returns
|
||||
return unescaped string (which needs to be freed)
|
||||
*/
|
||||
char*
|
||||
shell_unescape(const char* text)
|
||||
{
|
||||
GString *str;
|
||||
char *result = NULL;
|
||||
const char* readptr;
|
||||
char c;
|
||||
|
||||
if (!text)
|
||||
return NULL;
|
||||
|
||||
|
||||
/* look for the first \ - that's quick skipover if there's nothing to escape */
|
||||
readptr = text;
|
||||
while ((*readptr) && ((*readptr)!='\\')) readptr++;
|
||||
if (!(*readptr)) {
|
||||
result = g_strdup(text);
|
||||
return result;
|
||||
}
|
||||
str = g_string_new_len(text, readptr - text);
|
||||
|
||||
/* if we're here, we're standing on the first '\' */
|
||||
while ((c = *readptr))
|
||||
{
|
||||
if (c=='\\')
|
||||
{
|
||||
readptr++;
|
||||
switch ((c = *readptr))
|
||||
{
|
||||
case '\0': /* end of string! malformed escape string */
|
||||
goto out;
|
||||
|
||||
case 'n': g_string_append_c(str,'\n'); break;
|
||||
case 'r': g_string_append_c(str,'\r'); break;
|
||||
case 't': g_string_append_c(str,'\t'); break;
|
||||
|
||||
case ' ':
|
||||
case '\\':
|
||||
case '#':
|
||||
case '$':
|
||||
case '%':
|
||||
case '(':
|
||||
case ')':
|
||||
case '[':
|
||||
case ']':
|
||||
case '{':
|
||||
case '}':
|
||||
case '<':
|
||||
case '>':
|
||||
case '!':
|
||||
case '*':
|
||||
case '?':
|
||||
case '~':
|
||||
case '`':
|
||||
case '"':
|
||||
case ';':
|
||||
default:
|
||||
g_string_append_c(str,c); break;
|
||||
}
|
||||
}
|
||||
else /* got a normal character */
|
||||
{
|
||||
g_string_append_c(str,c);
|
||||
}
|
||||
readptr++;
|
||||
}
|
||||
out:
|
||||
|
||||
result = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Check if char in pointer contain escape'd chars
|
||||
|
||||
\params in
|
||||
string for checking
|
||||
|
||||
\returns
|
||||
return TRUE if string contain escaped chars
|
||||
otherwise return FALSE
|
||||
*/
|
||||
gboolean
|
||||
shell_is_char_escaped ( const char *in )
|
||||
{
|
||||
if (in == NULL || !*in || in[0] != '\\')
|
||||
return FALSE;
|
||||
if (shell_escape_toesc(in[1]))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -255,11 +255,6 @@ extern int ascii_alpha_to_cntrl (int ch);
|
||||
#undef Q_
|
||||
const char *Q_ (const char *s);
|
||||
|
||||
|
||||
gboolean shell_is_char_escaped ( const char * );
|
||||
char *shell_unescape( const char * );
|
||||
char *shell_escape( const char * );
|
||||
|
||||
#define str_dup_range(s_start, s_bound) (g_strndup(s_start, s_bound - s_start))
|
||||
|
||||
/*
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "../src/wtools.h" /* message() */
|
||||
#include "../src/main.h" /* print_vfs_message */
|
||||
#include "../src/util.h"
|
||||
#include "../src/strescape.h"
|
||||
#include "utilvfs.h"
|
||||
#include "xdirentry.h"
|
||||
#include "vfs.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user