aboutsummaryrefslogtreecommitdiff
path: root/src/wordsplit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wordsplit.c')
-rw-r--r--src/wordsplit.c138
1 files changed, 76 insertions, 62 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c
index c726239..671fcb9 100644
--- a/src/wordsplit.c
+++ b/src/wordsplit.c
@@ -176,6 +176,8 @@ wordsplit_init0 (struct wordsplit *wsp)
wsp->ws_head = wsp->ws_tail = NULL;
}
+char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
+
static int
wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
int flags)
@@ -234,6 +236,30 @@ wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
if (!(wsp->ws_flags & WRDSF_OPTIONS))
wsp->ws_options = 0;
+
+ if (wsp->ws_flags & WRDSF_ESCAPE)
+ {
+ if (!wsp->ws_escape[0])
+ wsp->ws_escape[0] = "";
+ if (!wsp->ws_escape[1])
+ wsp->ws_escape[1] = "";
+ }
+ else
+ {
+ if (wsp->ws_flags & WRDSF_CESCAPES)
+ {
+ wsp->ws_escape[0] = wordsplit_c_escape_tab;
+ wsp->ws_escape[1] = wordsplit_c_escape_tab;
+ wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
+ | WRDSO_XESC_QUOTE | WRDSO_XESC_WORD;
+ }
+ else
+ {
+ wsp->ws_escape[0] = "";
+ wsp->ws_escape[1] = "\\\\\"\"";
+ wsp->ws_options |= WRDSO_BSKEEP_QUOTE;
+ }
+ }
wsp->ws_endp = 0;
@@ -551,13 +577,14 @@ coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
return 0;
}
+static void wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
+ char *dst, const char *src,
+ size_t n);
+
static int
wsnode_quoteremoval (struct wordsplit *wsp)
{
struct wordsplit_node *p;
- void (*uqfn) (char *, const char *, size_t) =
- (wsp->ws_flags & WRDSF_CESCAPES) ?
- wordsplit_c_unquote_copy : wordsplit_sh_unquote_copy;
for (p = wsp->ws_head; p; p = p->next)
{
@@ -585,11 +612,8 @@ wsnode_quoteremoval (struct wordsplit *wsp)
p->flags |= _WSNF_WORD;
}
- if (wsp->ws_flags & WRDSF_ESCAPE)
- wordsplit_general_unquote_copy (p->v.word, str, slen,
- wsp->ws_escape);
- else
- uqfn (p->v.word, str, slen);
+ wordsplit_string_unquote_copy (wsp, p->flags & _WSNF_QUOTE,
+ p->v.word, str, slen);
}
}
return 0;
@@ -1825,35 +1849,6 @@ scan_word (struct wordsplit *wsp, size_t start)
return _WRDS_OK;
}
-static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
-
-int
-wordsplit_c_unquote_char (int c)
-{
- char *p;
-
- for (p = quote_transtab; *p; p += 2)
- {
- if (*p == c)
- return p[1];
- }
- return c;
-}
-
-int
-wordsplit_c_quote_char (int c)
-{
- char *p;
-
- for (p = quote_transtab + sizeof (quote_transtab) - 2;
- p > quote_transtab; p -= 2)
- {
- if (*p == c)
- return p[-1];
- }
- return -1;
-}
-
#define to_num(c) \
(ISDIGIT(c) ? c - '0' : (ISXDIGIT(c) ? toupper(c) - 'A' + 10 : 255 ))
@@ -1894,7 +1889,7 @@ wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
len += 3;
else
{
- if (wordsplit_c_quote_char (*str) != -1)
+ if (wordsplit_c_quote_char (*str))
len += 2;
else
len += 4;
@@ -1903,47 +1898,56 @@ wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
return len;
}
-void
-wordsplit_general_unquote_copy (char *dst, const char *src, size_t n,
- const char *escapable)
+int
+wsplt_unquote_char (const char *transtab, int c)
{
- int i;
-
- for (i = 0; i < n;)
+ while (*transtab && transtab[1])
{
- if (src[i] == '\\' && i < n && strchr (escapable, src[i + 1]))
- i++;
- *dst++ = src[i++];
+ if (*transtab++ == c)
+ return *transtab;
+ ++transtab;
}
- *dst = 0;
+ return 0;
}
-void
-wordsplit_sh_unquote_copy (char *dst, const char *src, size_t n)
+int
+wsplt_quote_char (const char *transtab, int c)
{
- int i;
-
- for (i = 0; i < n;)
+ for (; *transtab && transtab[1]; transtab += 2)
{
- if (src[i] == '\\')
- i++;
- *dst++ = src[i++];
+ if (transtab[1] == c)
+ return *transtab;
}
- *dst = 0;
+ return 0;
+}
+
+int
+wordsplit_c_unquote_char (int c)
+{
+ return wsplt_unquote_char (wordsplit_c_escape_tab, c);
+}
+
+int
+wordsplit_c_quote_char (int c)
+{
+ return wsplt_quote_char (wordsplit_c_escape_tab, c);
}
void
-wordsplit_c_unquote_copy (char *dst, const char *src, size_t n)
+wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
+ char *dst, const char *src, size_t n)
{
int i = 0;
int c;
+ inquote = !!inquote;
while (i < n)
{
if (src[i] == '\\')
{
++i;
- if (src[i] == 'x' || src[i] == 'X')
+ if (WRDSO_ESC_TEST (ws, inquote, WRDSO_XESC)
+ && (src[i] == 'x' || src[i] == 'X'))
{
if (n - i < 2)
{
@@ -1966,7 +1970,8 @@ wordsplit_c_unquote_copy (char *dst, const char *src, size_t n)
}
}
}
- else if ((unsigned char) src[i] < 128 && ISDIGIT (src[i]))
+ else if (WRDSO_ESC_TEST (ws, inquote, WRDSO_OESC)
+ && (unsigned char) src[i] < 128 && ISDIGIT (src[i]))
{
if (n - i < 1)
{
@@ -1988,8 +1993,17 @@ wordsplit_c_unquote_copy (char *dst, const char *src, size_t n)
}
}
}
+ else if ((c = wsplt_unquote_char (ws->ws_escape[inquote], src[i])))
+ {
+ *dst++ = c;
+ ++i;
+ }
else
- *dst++ = wordsplit_c_unquote_char (src[i++]);
+ {
+ if (WRDSO_ESC_TEST (ws, inquote, WRDSO_BSKEEP))
+ *dst++ = '\\';
+ *dst++ = src[i++];
+ }
}
else
*dst++ = src[i++];
@@ -2023,7 +2037,7 @@ wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
{
int c = wordsplit_c_quote_char (*src);
*dst++ = '\\';
- if (c != -1)
+ if (c)
*dst++ = c;
else
{

Return to:

Send suggestions and report system problems to the System administrator.