summaryrefslogtreecommitdiff
path: root/builtins/printf.def
diff options
context:
space:
mode:
Diffstat (limited to 'builtins/printf.def')
-rw-r--r--builtins/printf.def59
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';