diff --git a/common.c b/common.c
index e743f632e..a3d536671 100644
--- a/common.c
+++ b/common.c
@@ -551,12 +551,34 @@ int my_wcswidth( const wchar_t *c )
return res;
}
-wchar_t *quote_end( const wchar_t *in )
+const wchar_t *quote_end( const wchar_t *pos )
{
- return wcschr( in+1, *in );
+ wchar_t c = *pos;
+
+ while( 1 )
+ {
+ pos++;
+
+ if( !*pos )
+ return 0;
+
+ if( *pos == L'\\')
+ {
+ pos++;
+ }
+ else
+ {
+ if( *pos == c )
+ {
+ return pos;
+ }
+ }
+ }
+ return 0;
+
}
-
+
const wchar_t *wsetlocale(int category, const wchar_t *locale)
{
@@ -1137,6 +1159,30 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
*/
case 1:
{
+ if( c == L'\\' )
+ {
+ switch( in[++in_pos] )
+ {
+ case L'\'':
+ {
+ in[out_pos]=in[in_pos];
+ break;
+ }
+
+ case 0:
+ {
+ free(in);
+ return 0;
+ }
+
+ default:
+ {
+ in[out_pos++] = L'\\';
+ in[out_pos]= in[in_pos];
+ }
+ }
+
+ }
if( c == L'\'' )
{
in[out_pos] = INTERNAL_SEPARATOR;
@@ -1175,11 +1221,12 @@ wchar_t *unescape( const wchar_t * orig, int unescape_special )
}
case L'$':
+ case '"':
{
in[out_pos]=in[in_pos];
break;
}
-
+
default:
{
in[out_pos++] = L'\\';
diff --git a/common.h b/common.h
index 4208291cc..8bbdc9e1e 100644
--- a/common.h
+++ b/common.h
@@ -190,7 +190,7 @@ int my_wcswidth( const wchar_t *c );
\param in the position of the opening quote
*/
-wchar_t *quote_end( const wchar_t *in );
+const wchar_t *quote_end( const wchar_t *in );
/**
A call to this function will reset the error counter. Some
diff --git a/doc_src/doc.hdr b/doc_src/doc.hdr
index 7af9f7256..82db951ec 100644
--- a/doc_src/doc.hdr
+++ b/doc_src/doc.hdr
@@ -69,10 +69,13 @@ happens, the user can write a parameter within quotes, either '
(single quote) or " (double quote). There is one important difference
between single quoted and double quoted strings: When using double
quoted string, variable expansion still
-takes place. Other than that, a quoted parameter will not be
-parameter expanded, may contain spaces, and escape sequences are
-ignored. Single quotes have no special meaning withing double quotes
-and vice versa.
+takes place. Other than that, a quoted parameter will not be parameter
+expanded, may contain spaces, and escape sequences are ignored. The
+only backslash escape accepted within single quotes is \\', which
+escapes a single quote. The only backslash escapes accepted within
+double quotes are \\", which escapes a double quote, and \\$, which
+escapes a dollar character. Single quotes have no special meaning
+withing double quotes and vice versa.
Example:
@@ -82,7 +85,7 @@ Will remove the file 'cumbersome filename.txt', while
rm cumbersome filename.txt
-would remove the two files 'cumbersome' and 'filenmae.txt'.
+would remove the two files 'cumbersome' and 'filename.txt'.
\subsection escapes Escaping characters
diff --git a/reader.c b/reader.c
index d255c85f6..89404a6e1 100644
--- a/reader.c
+++ b/reader.c
@@ -1220,7 +1220,7 @@ static wchar_t get_quote( wchar_t *cmd, int l )
if( cmd[i] == L'\'' || cmd[i] == L'\"' )
{
- wchar_t *end = quote_end( &cmd[i] );
+ const wchar_t *end = quote_end( &cmd[i] );
//fwprintf( stderr, L"Jump %d\n", end-cmd );
if(( end == 0 ) || (!*end) || (end-cmd > l))
{
diff --git a/tokenizer.c b/tokenizer.c
index 435281b7b..b274b222a 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -272,11 +272,11 @@ static void read_string( tokenizer *tok )
case L'"':
{
- wchar_t *end = quote_end( tok->buff );
+ const wchar_t *end = quote_end( tok->buff );
tok->last_quote = *tok->buff;
if( end )
{
- tok->buff=end;
+ tok->buff=(wchar_t *)end;
}
else
{
@@ -311,10 +311,10 @@ static void read_string( tokenizer *tok )
case L'\'':
case L'\"':
{
- wchar_t *end = quote_end( tok->buff );
+ const wchar_t *end = quote_end( tok->buff );
if( end )
{
- tok->buff=end;
+ tok->buff=(wchar_t *)end;
}
else
do_loop = 0;