/* shquote - functions to quote and dequote strings */
-/* Copyright (C) 1999-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
#include "shmbchar.h"
#include "shmbutil.h"
-extern char *ansic_quote __P((char *, int, int *));
-extern int ansic_shouldquote __P((const char *));
+extern char *ansic_quote PARAMS((char *, int, int *));
+extern int ansic_shouldquote PARAMS((const char *));
/* Default set of characters that should be backslash-quoted in strings */
static const char bstab[256] =
const char *string;
{
register unsigned char c;
+ int mb_cur_max;
char *result, *r;
- const char *s;
+ size_t slen;
+ const char *s, *send;
+ DECLARE_MBSTATE;
+
+ slen = strlen (string);
+ send = string + slen;
+ mb_cur_max = MB_CUR_MAX;
result = (char *)xmalloc (3 + (2 * strlen (string)));
r = result;
/* Backslash-newline disappears within double quotes, so don't add one. */
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
-#if 0
- /* Assume that the string will not be further expanded. */
- else if (c == CTLESC || c == CTLNUL)
- *r++ = CTLESC; /* could be '\\'? */
+
+#if defined (HANDLE_MULTIBYTE)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
+ {
+ COPY_CHAR_P (r, s, send);
+ s--; /* compensate for auto-increment in loop above */
+ continue;
+ }
#endif
+ /* Assume that the string will not be further expanded, so no need to
+ add CTLESC to protect CTLESC or CTLNUL. */
*r++ = c;
}
int slen, flags;
{
char *r, *ret;
- int rlen;
+ const char *send;
+ int rlen, mb_cur_max;
+ DECLARE_MBSTATE;
+ send = s + slen;
+ mb_cur_max = flags ? MB_CUR_MAX : 1;
rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
ret = r = (char *)xmalloc (rlen);
-
+
*r++ = '"';
while (*s)
{
if (flags && *s == '"')
*r++ = '\\';
+
+#if defined (HANDLE_MULTIBYTE)
+ if (flags && ((locale_utf8locale && (*s & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (*s) == 0)))
+ {
+ COPY_CHAR_P (r, s, send);
+ continue;
+ }
+#endif
*r++ = *s++;
}
*r++ = '"';
*r++ = c;
continue;
}
- if (mb_cur_max > 1 && is_basic (c) == 0)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
{
COPY_CHAR_P (r, s, send);
s--; /* compensate for auto-increment in loop above */
char *string;
{
unsigned char c;
- char *result, *r, *s;
-
- result = (char *)xmalloc (2 * strlen (string) + 1);
+ char *result, *r, *s, *send;
+ size_t slen;
+ int mb_cur_max;
+ DECLARE_MBSTATE;
+
+ slen = strlen (string);
+ send = string + slen;
+ mb_cur_max = MB_CUR_MAX;
+ result = (char *)xmalloc (2 * slen + 1);
for (r = result, s = string; s && (c = *s); s++)
{
- if (sh_syntaxtab[c] & CBSDQUOTE)
+ /* Backslash-newline disappears within double quotes, so don't add one. */
+ if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
- /* I should probably add flags for these to sh_syntaxtab[] */
+ /* I should probably use the CSPECL flag for these in sh_syntaxtab[] */
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
+#if defined (HANDLE_MULTIBYTE)
+ if ((locale_utf8locale && (c & 0x80)) ||
+ (locale_utf8locale == 0 && mb_cur_max > 1 && is_basic (c) == 0))
+ {
+ COPY_CHAR_P (r, s, send);
+ s--; /* compensate for auto-increment in loop above */
+ continue;
+ }
+#endif
+
*r++ = c;
}