X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Fsh%2Fstrtrans.c;h=ae88e694db67e6e9349c318a5de736873d6e60b7;hb=ac50fbac377e32b98d2de396f016ea81e8ee9961;hp=2265782f8ee8d41f19e5b557527dff19e9355ead;hpb=4539d736f1aff232857a854fd2a68df0c98d9f34;p=platform%2Fupstream%2Fbash.git diff --git a/lib/sh/strtrans.c b/lib/sh/strtrans.c index 2265782..ae88e69 100644 --- a/lib/sh/strtrans.c +++ b/lib/sh/strtrans.c @@ -1,6 +1,6 @@ /* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */ -/* Copyright (C) 2000-2010 Free Software Foundation, Inc. +/* Copyright (C) 2000-2011 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -30,6 +30,9 @@ #include "shell.h" +#include "shmbchar.h" +#include "shmbutil.h" + #ifdef ESC #undef ESC #endif @@ -74,7 +77,7 @@ ansicstr (string, len, flags, sawc, rlen) case 'a': c = '\a'; break; case 'v': c = '\v'; break; #else - case 'a': c = '\007'; break; + case 'a': c = (int) 0x07; break; case 'v': c = (int) 0x0B; break; #endif case 'b': c = '\b'; break; @@ -144,7 +147,7 @@ ansicstr (string, len, flags, sawc, rlen) *r++ = '\\'; /* c remains unchanged */ break; } - else if (v <= UCHAR_MAX) + else if (v <= 0x7f) /* <= 0x7f translates directly */ { c = v; break; @@ -208,6 +211,11 @@ ansic_quote (str, flags, rlen) char *r, *ret, *s; int l, rsize; unsigned char c; + size_t clen; + int b; +#if defined (HANDLE_MULTIBYTE) + wchar_t wc; +#endif if (str == 0 || *str == 0) return ((char *)0); @@ -219,10 +227,13 @@ ansic_quote (str, flags, rlen) *r++ = '$'; *r++ = '\''; - for (s = str, l = 0; *s; s++) + s = str; + + for (s = str; c = *s; s++) { - c = *s; - l = 1; /* 1 == add backslash; 0 == no backslash */ + b = l = 1; /* 1 == add backslash; 0 == no backslash */ + clen = 1; + switch (c) { case ESC: c = 'E'; break; @@ -230,7 +241,7 @@ ansic_quote (str, flags, rlen) case '\a': c = 'a'; break; case '\v': c = 'v'; break; #else - case '\007': c = 'a'; break; + case 0x07: c = 'a'; break; case 0x0b: c = 'v'; break; #endif @@ -243,7 +254,14 @@ ansic_quote (str, flags, rlen) case '\'': break; default: +#if defined (HANDLE_MULTIBYTE) + b = is_basic (c); + /* XXX - clen comparison to 0 is dicey */ + if ((b == 0 && ((clen = mbrtowc (&wc, s, MB_CUR_MAX, 0)) < 0 || MB_INVALIDCH (clen) || iswprint (wc) == 0)) || + (b == 1 && ISPRINT (c) == 0)) +#else if (ISPRINT (c) == 0) +#endif { *r++ = '\\'; *r++ = TOCHAR ((c >> 6) & 07); @@ -254,9 +272,20 @@ ansic_quote (str, flags, rlen) l = 0; break; } + if (b == 0 && clen == 0) + break; + if (l) *r++ = '\\'; - *r++ = c; + + if (clen == 1) + *r++ = c; + else + { + for (b = 0; b < (int)clen; b++) + *r++ = (unsigned char)s[b]; + s += clen - 1; /* -1 because of the increment above */ + } } *r++ = '\''; @@ -266,6 +295,37 @@ ansic_quote (str, flags, rlen) return ret; } +#if defined (HANDLE_MULTIBYTE) +int +ansic_wshouldquote (string) + const char *string; +{ + const wchar_t *wcs; + wchar_t wcc; + + wchar_t *wcstr = NULL; + size_t slen; + + + slen = mbstowcs (wcstr, string, 0); + + if (slen == -1) + slen = 0; + wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1)); + mbstowcs (wcstr, string, slen + 1); + + for (wcs = wcstr; wcc = *wcs; wcs++) + if (iswprint(wcc) == 0) + { + free (wcstr); + return 1; + } + + free (wcstr); + return 0; +} +#endif + /* return 1 if we need to quote with $'...' because of non-printing chars. */ int ansic_shouldquote (string) @@ -278,8 +338,14 @@ ansic_shouldquote (string) return 0; for (s = string; c = *s; s++) - if (ISPRINT (c) == 0) - return 1; + { +#if defined (HANDLE_MULTIBYTE) + if (is_basic (c) == 0) + return (ansic_wshouldquote (s)); +#endif + if (ISPRINT (c) == 0) + return 1; + } return 0; }