diff options
Diffstat (limited to 'builtins/printf.def')
-rw-r--r-- | builtins/printf.def | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/builtins/printf.def b/builtins/printf.def index 277566f8..496da9b6 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -224,6 +224,10 @@ printf_builtin (list) int ch, fieldwidth, precision; int have_fieldwidth, have_precision; char convch, thisch, nextch, *format, *modstart, *fmt, *start; +#if defined (HANDLE_MULTIBYTE) + char mbch[25]; /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/ + int mbind; +#endif conversion_error = 0; retval = EXECUTION_SUCCESS; @@ -301,8 +305,17 @@ printf_builtin (list) fmt++; /* A NULL third argument to tescape means to bypass the special processing for arguments to %b. */ +#if defined (HANDLE_MULTIBYTE) + /* Accommodate possible use of \u or \U, which can result in + multibyte characters */ + memset (mbch, '\0', sizeof (mbch)); + fmt += tescape (fmt, mbch, (int *)NULL); + for (mbind = 0; mbch[mbind]; mbind++) + PC (mbch[mbind]); +#else fmt += tescape (fmt, &nextch, (int *)NULL); PC (nextch); +#endif fmt--; /* for loop will increment it for us again */ continue; } @@ -743,14 +756,10 @@ tescape (estart, cp, sawc) *cp = evalue & 0xFF; break; - /* And, as another extension, we allow \xNNN, where each N is a + /* And, as another extension, we allow \xNN, where each N is a hex digit. */ case 'x': -#if 0 - for (evalue = 0; ISXDIGIT ((unsigned char)*p); p++) -#else for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) -#endif evalue = (evalue * 16) + HEXVALUE (*p); if (p == estart + 1) { @@ -761,6 +770,28 @@ tescape (estart, cp, sawc) *cp = evalue & 0xFF; break; +#if defined (HANDLE_MULTIBYTE) + case 'u': + case 'U': + temp = (c == 'u') ? 4 : 8; /* \uNNNN \UNNNNNNNN */ + for (evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++) + evalue = (evalue * 16) + HEXVALUE (*p); + if (p == estart + 1) + { + builtin_error (_("missing unicode digit for \\%c"), c); + *cp = '\\'; + return 0; + } + if (evalue <= UCHAR_MAX) + *cp = evalue; + else + { + temp = u32cconv (evalue, cp); + cp[temp] = '\0'; + } + break; +#endif + case '\\': /* \\ -> \ */ *cp = c; break; @@ -799,12 +830,12 @@ bexpand (string, len, sawc, lenp) { int temp; char *ret, *r, *s, c; +#if defined (HANDLE_MULTIBYTE) + char mbch[25]; + int mbind; +#endif -#if 0 - if (string == 0 || *string == '\0') -#else if (string == 0 || len == 0) -#endif { if (sawc) *sawc = 0; @@ -823,7 +854,12 @@ bexpand (string, len, sawc, lenp) continue; } temp = 0; +#if defined (HANDLE_MULTIBYTE) + memset (mbch, '\0', sizeof (mbch)); + s += tescape (s, mbch, &temp); +#else s += tescape (s, &c, &temp); +#endif if (temp) { if (sawc) @@ -831,7 +867,12 @@ bexpand (string, len, sawc, lenp) break; } +#if defined (HANDLE_MULTIBYTE) + for (mbind = 0; mbch[mbind]; mbind++) + *r++ = mbch[mbind]; +#else *r++ = c; +#endif } *r = '\0'; |