Bash-4.2 patch 4
[platform/upstream/bash.git] / builtins / printf.def
1 This file is printf.def, from which is created printf.c.
2 It implements the builtin "printf" in Bash.
3
4 Copyright (C) 1997-2010 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Bash.  If not, see <http://www.gnu.org/licenses/>.
20
21 $PRODUCES printf.c
22
23 $BUILTIN printf
24 $FUNCTION printf_builtin
25 $SHORT_DOC printf [-v var] format [arguments]
26 Formats and prints ARGUMENTS under control of the FORMAT.
27
28 Options:
29   -v var        assign the output to shell variable VAR rather than
30                 display it on the standard output
31
32 FORMAT is a character string which contains three types of objects: plain
33 characters, which are simply copied to standard output; character escape
34 sequences, which are converted and copied to the standard output; and
35 format specifications, each of which causes printing of the next successive
36 argument.
37
38 In addition to the standard format specifications described in printf(1)
39 and printf(3), printf interprets:
40
41   %b    expand backslash escape sequences in the corresponding argument
42   %q    quote the argument in a way that can be reused as shell input
43   %(fmt)T output the date-time string resulting from using FMT as a format
44         string for strftime(3)
45
46 Exit Status:
47 Returns success unless an invalid option is given or a write or assignment
48 error occurs.
49 $END
50
51 #include <config.h>
52
53 #include "../bashtypes.h"
54
55 #include <errno.h>
56 #if defined (HAVE_LIMITS_H)
57 #  include <limits.h>
58 #else
59    /* Assume 32-bit ints. */
60 #  define INT_MAX               2147483647
61 #  define INT_MIN               (-2147483647-1)
62 #endif
63
64 #if defined (PREFER_STDARG)
65 #  include <stdarg.h>
66 #else
67 #  include <varargs.h>
68 #endif
69
70 #include <stdio.h>
71 #include <chartypes.h>
72
73 #ifdef HAVE_INTTYPES_H
74 #  include <inttypes.h>
75 #endif
76
77 #include "posixtime.h"
78 #include "../bashansi.h"
79 #include "../bashintl.h"
80
81 #define NEED_STRFTIME_DECL
82
83 #include "../shell.h"
84 #include "shmbutil.h"
85 #include "stdc.h"
86 #include "bashgetopt.h"
87 #include "common.h"
88
89 #if defined (PRI_MACROS_BROKEN)
90 #  undef PRIdMAX
91 #endif
92
93 #if !defined (PRIdMAX)
94 #  if HAVE_LONG_LONG
95 #    define PRIdMAX     "lld"
96 #  else
97 #    define PRIdMAX     "ld"
98 #  endif
99 #endif
100
101 #if !defined (errno)
102 extern int errno;
103 #endif
104
105 #define PC(c) \
106   do { \
107     char b[2]; \
108     tw++; \
109     b[0] = c; b[1] = '\0'; \
110     if (vflag) \
111       vbadd (b, 1); \
112     else \
113       putchar (c); \
114   } while (0)
115
116 #define PF(f, func) \
117   do { \
118     int nw; \
119     clearerr (stdout); \
120     if (have_fieldwidth && have_precision) \
121       nw = vflag ? vbprintf (f, fieldwidth, precision, func) : printf (f, fieldwidth, precision, func); \
122     else if (have_fieldwidth) \
123       nw = vflag ? vbprintf (f, fieldwidth, func) : printf (f, fieldwidth, func); \
124     else if (have_precision) \
125       nw = vflag ? vbprintf (f, precision, func) : printf (f, precision, func); \
126     else \
127       nw = vflag ? vbprintf (f, func) : printf (f, func); \
128     tw += nw; \
129     if (ferror (stdout)) \
130       { \
131         sh_wrerror (); \
132         clearerr (stdout); \
133         return (EXECUTION_FAILURE); \
134       } \
135   } while (0)
136
137 /* We free the buffer used by mklong() if it's `too big'. */
138 #define PRETURN(value) \
139   do \
140     { \
141       if (vflag) \
142         { \
143           bind_printf_variable  (vname, vbuf, 0); \
144           stupidly_hack_special_variables (vname); \
145         } \
146       if (conv_bufsize > 4096 ) \
147         { \
148           free (conv_buf); \
149           conv_bufsize = 0; \
150           conv_buf = 0; \
151         } \
152       if (vbsize > 4096) \
153         { \
154           free (vbuf); \
155           vbsize = 0; \
156           vbuf = 0; \
157         } \
158       else if (vbuf) \
159         vbuf[0] = 0; \
160       terminate_immediately--; \
161       fflush (stdout); \
162       if (ferror (stdout)) \
163         { \
164           sh_wrerror (); \
165           clearerr (stdout); \
166           return (EXECUTION_FAILURE); \
167         } \
168       return (value); \
169     } \
170   while (0)
171
172 #define SKIP1 "#'-+ 0"
173 #define LENMODS "hjlLtz"
174
175 extern time_t shell_start_time;
176
177 #if !HAVE_ASPRINTF
178 extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
179 #endif
180
181 #if !HAVE_VSNPRINTF
182 extern int vsnprintf __P((char *, size_t, const char *, va_list)) __attribute__((__format__ (printf, 3, 0)));
183 #endif
184
185 static void printf_erange __P((char *));
186 static int printstr __P((char *, char *, int, int, int));
187 static int tescape __P((char *, char *, int *, int *));
188 static char *bexpand __P((char *, int, int *, int *));
189 static char *vbadd __P((char *, int));
190 static int vbprintf __P((const char *, ...)) __attribute__((__format__ (printf, 1, 2)));
191 static char *mklong __P((char *, char *, size_t));
192 static int getchr __P((void));
193 static char *getstr __P((void));
194 static int  getint __P((void));
195 static intmax_t getintmax __P((void));
196 static uintmax_t getuintmax __P((void));
197 static SHELL_VAR *bind_printf_variable __P((char *, char *, int));
198
199 #if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
200 typedef long double floatmax_t;
201 #  define FLOATMAX_CONV "L"
202 #  define strtofltmax   strtold
203 #else
204 typedef double floatmax_t;
205 #  define FLOATMAX_CONV ""
206 #  define strtofltmax   strtod
207 #endif
208 static floatmax_t getfloatmax __P((void));
209
210 static intmax_t asciicode __P((void));
211
212 static WORD_LIST *garglist;
213 static int retval;
214 static int conversion_error;
215
216 /* printf -v var support */
217 static int vflag = 0;
218 static char *vbuf, *vname;
219 static size_t vbsize;
220 static int vblen;
221
222 static intmax_t tw;
223
224 static char *conv_buf;
225 static size_t conv_bufsize;
226
227 int
228 printf_builtin (list)
229      WORD_LIST *list;
230 {
231   int ch, fieldwidth, precision;
232   int have_fieldwidth, have_precision;
233   char convch, thisch, nextch, *format, *modstart, *fmt, *start;
234 #if defined (HANDLE_MULTIBYTE)
235   char mbch[25];                /* 25 > MB_LEN_MAX, plus can handle 4-byte UTF-8 and large Unicode characters*/
236   int mbind, mblen;
237 #endif
238
239   conversion_error = 0;
240   retval = EXECUTION_SUCCESS;
241
242   vflag = 0;
243
244   reset_internal_getopt ();
245   while ((ch = internal_getopt (list, "v:")) != -1)
246     {
247       switch (ch)
248         {
249         case 'v':
250           vname = list_optarg;
251 #if defined (ARRAY_VARS)
252           if (legal_identifier (vname) || valid_array_reference (vname))
253 #else
254           if (legal_identifier (vname))
255 #endif
256             {
257               vflag = 1;
258               vblen = 0;
259               if (vbuf)
260                 vbuf[0] = 0;
261             }
262           else
263             {
264               sh_invalidid (vname);
265               return (EX_USAGE);
266             }
267           break;
268         default:
269           builtin_usage ();
270           return (EX_USAGE);
271         }
272     }
273   list = loptend;       /* skip over possible `--' */
274
275   if (list == 0)
276     {
277       builtin_usage ();
278       return (EX_USAGE);
279     }
280
281   if (list->word->word == 0 || list->word->word[0] == '\0')
282     return (EXECUTION_SUCCESS);
283
284   format = list->word->word;
285   tw = 0;
286
287   garglist = list->next;
288
289   /* If the format string is empty after preprocessing, return immediately. */
290   if (format == 0 || *format == 0)
291     return (EXECUTION_SUCCESS);
292
293   terminate_immediately++;
294           
295   /* Basic algorithm is to scan the format string for conversion
296      specifications -- once one is found, find out if the field
297      width or precision is a '*'; if it is, gather up value.  Note,
298      format strings are reused as necessary to use up the provided
299      arguments, arguments of zero/null string are provided to use
300      up the format string. */
301   do
302     {
303       tw = 0;
304       /* find next format specification */
305       for (fmt = format; *fmt; fmt++)
306         {
307           precision = fieldwidth = 0;
308           have_fieldwidth = have_precision = 0;
309
310           if (*fmt == '\\')
311             {
312               fmt++;
313               /* A NULL third argument to tescape means to bypass the
314                  special processing for arguments to %b. */
315 #if defined (HANDLE_MULTIBYTE)
316               /* Accommodate possible use of \u or \U, which can result in
317                  multibyte characters */
318               memset (mbch, '\0', sizeof (mbch));
319               fmt += tescape (fmt, mbch, &mblen, (int *)NULL);
320               for (mbind = 0; mbind < mblen; mbind++)
321                 PC (mbch[mbind]);
322 #else
323               fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL);
324               PC (nextch);
325 #endif
326               fmt--;    /* for loop will increment it for us again */
327               continue;
328             }
329
330           if (*fmt != '%')
331             {
332               PC (*fmt);
333               continue;
334             }
335
336           /* ASSERT(*fmt == '%') */
337           start = fmt++;
338
339           if (*fmt == '%')              /* %% prints a % */
340             {
341               PC ('%');
342               continue;
343             }
344
345           /* found format specification, skip to field width */
346           for (; *fmt && strchr(SKIP1, *fmt); ++fmt)
347             ;
348
349           /* Skip optional field width. */
350           if (*fmt == '*')
351             {
352               fmt++;
353               have_fieldwidth = 1;
354               fieldwidth = getint ();
355             }
356           else
357             while (DIGIT (*fmt))
358               fmt++;
359
360           /* Skip optional '.' and precision */
361           if (*fmt == '.')
362             {
363               ++fmt;
364               if (*fmt == '*')
365                 {
366                   fmt++;
367                   have_precision = 1;
368                   precision = getint ();
369                 }
370               else
371                 {
372                   /* Negative precisions are allowed but treated as if the
373                      precision were missing; I would like to allow a leading
374                      `+' in the precision number as an extension, but lots
375                      of asprintf/fprintf implementations get this wrong. */
376 #if 0
377                   if (*fmt == '-' || *fmt == '+')
378 #else
379                   if (*fmt == '-')
380 #endif
381                     fmt++;
382                   while (DIGIT (*fmt))
383                     fmt++;
384                 }
385             }
386
387           /* skip possible format modifiers */
388           modstart = fmt;
389           while (*fmt && strchr (LENMODS, *fmt))
390             fmt++;
391             
392           if (*fmt == 0)
393             {
394               builtin_error (_("`%s': missing format character"), start);
395               PRETURN (EXECUTION_FAILURE);
396             }
397
398           convch = *fmt;
399           thisch = modstart[0];
400           nextch = modstart[1];
401           modstart[0] = convch;
402           modstart[1] = '\0';
403
404           switch(convch)
405             {
406             case 'c':
407               {
408                 char p;
409
410                 p = getchr ();
411                 PF(start, p);
412                 break;
413               }
414
415             case 's':
416               {
417                 char *p;
418
419                 p = getstr ();
420                 PF(start, p);
421                 break;
422               }
423
424             case '(':
425               {
426                 char *timefmt, timebuf[128], *t;
427                 int n;
428                 intmax_t arg;
429                 time_t secs;
430                 struct tm *tm;
431
432                 modstart[1] = nextch;   /* restore char after left paren */
433                 timefmt = xmalloc (strlen (fmt) + 3);
434                 fmt++;  /* skip over left paren */
435                 for (t = timefmt, n = 1; *fmt; )
436                   {
437                     if (*fmt == '(')
438                       n++;
439                     else if (*fmt == ')')
440                       n--;
441                     if (n == 0)
442                       break;
443                     *t++ = *fmt++;
444                   }
445                 *t = '\0';
446                 if (*++fmt != 'T')
447                   {
448                     builtin_warning (_("`%c': invalid time format specification"), *fmt);
449                     fmt = start;
450                     free (timefmt);
451                     PC (*fmt);
452                     continue;
453                   }
454                 if (timefmt[0] == '\0')
455                   {
456                     timefmt[0] = '%';
457                     timefmt[1] = 'X';   /* locale-specific current time - should we use `+'? */
458                     timefmt[2] = '\0';
459                   }
460                 /* argument is seconds since the epoch with special -1 and -2 */
461                 arg = getintmax ();
462                 if (arg == -1)
463                   secs = NOW;           /* roughly date +%s */
464                 else if (arg == -2)
465                   secs = shell_start_time;      /* roughly $SECONDS */
466                 else
467                   secs = arg;
468                 tm = localtime (&secs);
469                 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
470                 free (timefmt);
471                 if (n == 0)
472                   timebuf[0] = '\0';
473                 else
474                   timebuf[sizeof(timebuf) - 1] = '\0';
475                 /* convert to %s format that preserves fieldwidth and precision */
476                 modstart[0] = 's';
477                 modstart[1] = '\0';
478                 n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
479                 if (n < 0)
480                   {
481                     sh_wrerror ();
482                     clearerr (stdout);
483                     PRETURN (EXECUTION_FAILURE);
484                   }
485                 break;
486               }
487
488             case 'n':
489               {
490                 char *var;
491
492                 var = getstr ();
493                 if (var && *var)
494                   {
495                     if (legal_identifier (var))
496                       bind_var_to_int (var, tw);
497                     else
498                       {
499                         sh_invalidid (var);
500                         PRETURN (EXECUTION_FAILURE);
501                       }
502                   }
503                 break;
504               }
505
506             case 'b':           /* expand escapes in argument */
507               {
508                 char *p, *xp;
509                 int rlen, r;
510
511                 p = getstr ();
512                 ch = rlen = r = 0;
513                 xp = bexpand (p, strlen (p), &ch, &rlen);
514
515                 if (xp)
516                   {
517                     /* Have to use printstr because of possible NUL bytes
518                        in XP -- printf does not handle that well. */
519                     r = printstr (start, xp, rlen, fieldwidth, precision);
520                     if (r < 0)
521                       {
522                         sh_wrerror ();
523                         clearerr (stdout);
524                         retval = EXECUTION_FAILURE;
525                       }
526                     free (xp);
527                   }
528
529                 if (ch || r < 0)
530                   PRETURN (retval);
531                 break;
532               }
533
534             case 'q':           /* print with shell quoting */
535               {
536                 char *p, *xp;
537                 int r;
538
539                 r = 0;
540                 p = getstr ();
541                 if (p && *p == 0)       /* XXX - getstr never returns null */
542                   xp = savestring ("''");
543                 else if (ansic_shouldquote (p))
544                   xp = ansic_quote (p, 0, (int *)0);
545                 else
546                   xp = sh_backslash_quote (p);
547                 if (xp)
548                   {
549                     /* Use printstr to get fieldwidth and precision right. */
550                     r = printstr (start, xp, strlen (xp), fieldwidth, precision);
551                     if (r < 0)
552                       {
553                         sh_wrerror ();
554                         clearerr (stdout);
555                       }
556                     free (xp);
557                   }
558
559                 if (r < 0)
560                   PRETURN (EXECUTION_FAILURE);
561                 break;
562               }
563
564             case 'd':
565             case 'i':
566               {
567                 char *f;
568                 long p;
569                 intmax_t pp;
570
571                 p = pp = getintmax ();
572                 if (p != pp)
573                   {
574                     f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
575                     PF (f, pp);
576                   }
577                 else
578                   {
579                     /* Optimize the common case where the integer fits
580                        in "long".  This also works around some long
581                        long and/or intmax_t library bugs in the common
582                        case, e.g. glibc 2.2 x86.  */
583                     f = mklong (start, "l", 1);
584                     PF (f, p);
585                   }
586                 break;
587               }
588
589             case 'o':
590             case 'u':
591             case 'x':
592             case 'X':
593               {
594                 char *f;
595                 unsigned long p;
596                 uintmax_t pp;
597
598                 p = pp = getuintmax ();
599                 if (p != pp)
600                   {
601                     f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
602                     PF (f, pp);
603                   }
604                 else
605                   {
606                     f = mklong (start, "l", 1);
607                     PF (f, p);
608                   }
609                 break;
610               }
611
612             case 'e':
613             case 'E':
614             case 'f':
615             case 'F':
616             case 'g':
617             case 'G':
618 #if defined (HAVE_PRINTF_A_FORMAT)
619             case 'a':
620             case 'A':
621 #endif
622               {
623                 char *f;
624                 floatmax_t p;
625
626                 p = getfloatmax ();
627                 f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
628                 PF (f, p);
629                 break;
630               }
631
632             /* We don't output unrecognized format characters; we print an
633                error message and return a failure exit status. */
634             default:
635               builtin_error (_("`%c': invalid format character"), convch);
636               PRETURN (EXECUTION_FAILURE);
637             }
638
639           modstart[0] = thisch;
640           modstart[1] = nextch;
641         }
642
643       if (ferror (stdout))
644         {
645           sh_wrerror ();
646           clearerr (stdout);
647           PRETURN (EXECUTION_FAILURE);
648         }
649     }
650   while (garglist && garglist != list->next);
651
652   if (conversion_error)
653     retval = EXECUTION_FAILURE;
654
655   PRETURN (retval);
656 }
657
658 static void
659 printf_erange (s)
660      char *s;
661 {
662   builtin_error (_("warning: %s: %s"), s, strerror(ERANGE));
663 }
664
665 /* We duplicate a lot of what printf(3) does here. */
666 static int
667 printstr (fmt, string, len, fieldwidth, precision)
668      char *fmt;                 /* format */
669      char *string;              /* expanded string argument */
670      int len;                   /* length of expanded string */
671      int fieldwidth;            /* argument for width of `*' */
672      int precision;             /* argument for precision of `*' */
673 {
674 #if 0
675   char *s;
676 #endif
677   int padlen, nc, ljust, i;
678   int fw, pr;                   /* fieldwidth and precision */
679
680 #if 0
681   if (string == 0 || *string == '\0')
682 #else
683   if (string == 0 || len == 0)
684 #endif
685     return 0;
686
687 #if 0
688   s = fmt;
689 #endif
690   if (*fmt == '%')
691     fmt++;
692
693   ljust = fw = 0;
694   pr = -1;
695
696   /* skip flags */
697   while (strchr (SKIP1, *fmt))
698     {
699       if (*fmt == '-')
700         ljust = 1;
701       fmt++;
702     }
703
704   /* get fieldwidth, if present */
705   if (*fmt == '*')
706     {
707       fmt++;
708       fw = fieldwidth;
709       if (fw < 0)
710         {
711           fw = -fw;
712           ljust = 1;
713         }
714     }
715   else if (DIGIT (*fmt))
716     {
717       fw = *fmt++ - '0';
718       while (DIGIT (*fmt))
719         fw = (fw * 10) + (*fmt++ - '0');
720     }
721
722   /* get precision, if present */
723   if (*fmt == '.')
724     {
725       fmt++;
726       if (*fmt == '*')
727         {
728           fmt++;
729           pr = precision;
730         }
731       else if (DIGIT (*fmt))
732         {
733           pr = *fmt++ - '0';
734           while (DIGIT (*fmt))
735             pr = (pr * 10) + (*fmt++ - '0');
736         }
737     }
738
739 #if 0
740   /* If we remove this, get rid of `s'. */
741   if (*fmt != 'b' && *fmt != 'q')
742     {
743       internal_error ("format parsing problem: %s", s);
744       fw = pr = 0;
745     }
746 #endif
747
748   /* chars from string to print */
749   nc = (pr >= 0 && pr <= len) ? pr : len;
750
751   padlen = fw - nc;
752   if (padlen < 0)
753     padlen = 0;
754   if (ljust)
755     padlen = -padlen;
756
757   /* leading pad characters */
758   for (; padlen > 0; padlen--)
759     PC (' ');
760
761   /* output NC characters from STRING */
762   for (i = 0; i < nc; i++)
763     PC (string[i]);
764
765   /* output any necessary trailing padding */
766   for (; padlen < 0; padlen++)
767     PC (' ');
768
769   return (ferror (stdout) ? -1 : 0);
770 }
771   
772 /* Convert STRING by expanding the escape sequences specified by the
773    POSIX standard for printf's `%b' format string.  If SAWC is non-null,
774    perform the processing appropriate for %b arguments.  In particular,
775    recognize `\c' and use that as a string terminator.  If we see \c, set
776    *SAWC to 1 before returning.  LEN is the length of STRING. */
777
778 /* Translate a single backslash-escape sequence starting at ESTART (the
779    character after the backslash) and return the number of characters
780    consumed by the sequence.  CP is the place to return the translated
781    value.  *SAWC is set to 1 if the escape sequence was \c, since that means
782    to short-circuit the rest of the processing.  If SAWC is null, we don't
783    do the \c short-circuiting, and \c is treated as an unrecognized escape
784    sequence; we also bypass the other processing specific to %b arguments.  */
785 static int
786 tescape (estart, cp, lenp, sawc)
787      char *estart;
788      char *cp;
789      int *lenp, *sawc;
790 {
791   register char *p;
792   int temp, c, evalue;
793   unsigned long uvalue;
794
795   p = estart;
796   if (lenp)
797     *lenp = 1;
798
799   switch (c = *p++)
800     {
801 #if defined (__STDC__)
802       case 'a': *cp = '\a'; break;
803 #else
804       case 'a': *cp = '\007'; break;
805 #endif
806
807       case 'b': *cp = '\b'; break;
808
809       case 'e':
810       case 'E': *cp = '\033'; break;    /* ESC -- non-ANSI */
811
812       case 'f': *cp = '\f'; break;
813
814       case 'n': *cp = '\n'; break;
815
816       case 'r': *cp = '\r'; break;
817
818       case 't': *cp = '\t'; break;
819
820       case 'v': *cp = '\v'; break;
821
822       /* The octal escape sequences are `\0' followed by up to three octal
823          digits (if SAWC), or `\' followed by up to three octal digits (if
824          !SAWC).  As an extension, we allow the latter form even if SAWC. */
825       case '0': case '1': case '2': case '3':
826       case '4': case '5': case '6': case '7':
827         evalue = OCTVALUE (c);
828         for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
829           evalue = (evalue * 8) + OCTVALUE (*p);
830         *cp = evalue & 0xFF;
831         break;
832
833       /* And, as another extension, we allow \xNN, where each N is a
834          hex digit. */
835       case 'x':
836         for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
837           evalue = (evalue * 16) + HEXVALUE (*p);
838         if (p == estart + 1)
839           {
840             builtin_error (_("missing hex digit for \\x"));
841             *cp = '\\';
842             return 0;
843           }
844         *cp = evalue & 0xFF;
845         break;
846
847 #if defined (HANDLE_MULTIBYTE)
848       case 'u':
849       case 'U':
850         temp = (c == 'u') ? 4 : 8;      /* \uNNNN \UNNNNNNNN */
851         for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
852           uvalue = (uvalue * 16) + HEXVALUE (*p);
853         if (p == estart + 1)
854           {
855             builtin_error (_("missing unicode digit for \\%c"), c);
856             *cp = '\\';
857             return 0;
858           }
859         if (uvalue <= UCHAR_MAX)
860           *cp = uvalue;
861         else
862           {
863             temp = u32cconv (uvalue, cp);
864             cp[temp] = '\0';
865             if (lenp)
866               *lenp = temp;
867           }
868         break;
869 #endif
870         
871       case '\\':        /* \\ -> \ */
872         *cp = c;
873         break;
874
875       /* SAWC == 0 means that \', \", and \? are recognized as escape
876          sequences, though the only processing performed is backslash
877          removal. */
878       case '\'': case '"': case '?':
879         if (!sawc)
880           *cp = c;
881         else
882           {
883             *cp = '\\';
884             return 0;
885           }
886         break;
887
888       case 'c':
889         if (sawc)
890           {
891             *sawc = 1;
892             break;
893           }
894       /* other backslash escapes are passed through unaltered */
895       default:
896         *cp = '\\';
897         return 0;
898       }
899   return (p - estart);
900 }
901
902 static char *
903 bexpand (string, len, sawc, lenp)
904      char *string;
905      int len, *sawc, *lenp;
906 {
907   int temp;
908   char *ret, *r, *s, c;
909 #if defined (HANDLE_MULTIBYTE)
910   char mbch[25];
911   int mbind, mblen;
912 #endif
913
914   if (string == 0 || len == 0)
915     {
916       if (sawc)
917         *sawc = 0;
918       if (lenp)
919         *lenp = 0;
920       return ((char *)NULL);
921     }
922
923   ret = (char *)xmalloc (len + 1);
924   for (r = ret, s = string; s && *s; )
925     {
926       c = *s++;
927       if (c != '\\' || *s == '\0')
928         {
929           *r++ = c;
930           continue;
931         }
932       temp = 0;
933 #if defined (HANDLE_MULTIBYTE)
934       memset (mbch, '\0', sizeof (mbch));
935       s += tescape (s, mbch, &mblen, &temp);
936 #else
937       s += tescape (s, &c, (int *)NULL, &temp);
938 #endif
939       if (temp)
940         {
941           if (sawc)
942             *sawc = 1;
943           break;
944         }
945
946 #if defined (HANDLE_MULTIBYTE)
947       for (mbind = 0; mbind < mblen; mbind++)
948         *r++ = mbch[mbind];
949 #else
950       *r++ = c;
951 #endif      
952     }
953
954   *r = '\0';
955   if (lenp)
956     *lenp = r - ret;
957   return ret;
958 }
959
960 static char *
961 vbadd (buf, blen)
962      char *buf;
963      int blen;
964 {
965   size_t nlen;
966
967   nlen = vblen + blen + 1;
968   if (nlen >= vbsize)
969     {
970       vbsize = ((nlen + 63) >> 6) << 6;
971       vbuf = (char *)xrealloc (vbuf, vbsize);
972     }
973
974   if (blen == 1)
975     vbuf[vblen++] = buf[0];
976   else if (blen > 1)
977     {
978       FASTCOPY (buf, vbuf  + vblen, blen);
979       vblen += blen;
980     }
981   vbuf[vblen] = '\0';
982
983 #ifdef DEBUG
984   if  (strlen (vbuf) != vblen)
985     internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
986 #endif
987
988   return vbuf;
989 }
990
991 static int
992 #if defined (PREFER_STDARG)
993 vbprintf (const char *format, ...)
994 #else
995 vbprintf (format, va_alist)
996   const char *format;
997   va_dcl
998 #endif
999 {
1000   va_list args;
1001   size_t nlen;
1002   int blen;
1003
1004   SH_VA_START (args, format);
1005   blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
1006   va_end (args);
1007
1008   nlen = vblen + blen + 1;
1009   if (nlen >= vbsize)
1010     {
1011       vbsize = ((nlen + 63) >> 6) << 6;
1012       vbuf = (char *)xrealloc (vbuf, vbsize);
1013       SH_VA_START (args, format);
1014       blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
1015       va_end (args);
1016     }
1017
1018   vblen += blen;
1019   vbuf[vblen] = '\0';
1020
1021 #ifdef DEBUG
1022   if  (strlen (vbuf) != vblen)
1023     internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
1024 #endif
1025   
1026   return (blen);
1027 }
1028
1029 static char *
1030 mklong (str, modifiers, mlen)
1031      char *str;
1032      char *modifiers;
1033      size_t mlen;
1034 {
1035   size_t len, slen;
1036
1037   slen = strlen (str);
1038   len = slen + mlen + 1;
1039
1040   if (len > conv_bufsize)
1041     {
1042       conv_bufsize = (((len + 1023) >> 10) << 10);
1043       conv_buf = (char *)xrealloc (conv_buf, conv_bufsize);
1044     }
1045
1046   FASTCOPY (str, conv_buf, slen - 1);
1047   FASTCOPY (modifiers, conv_buf + slen - 1, mlen);
1048
1049   conv_buf[len - 2] = str[slen - 1];
1050   conv_buf[len - 1] = '\0';
1051   return (conv_buf);
1052 }
1053
1054 static int
1055 getchr ()
1056 {
1057   int ret;
1058
1059   if (garglist == 0)
1060     return ('\0');
1061
1062   ret = (int)garglist->word->word[0];
1063   garglist = garglist->next;
1064   return ret;
1065 }
1066
1067 static char *
1068 getstr ()
1069 {
1070   char *ret;
1071
1072   if (garglist == 0)
1073     return ("");
1074
1075   ret = garglist->word->word;
1076   garglist = garglist->next;
1077   return ret;
1078 }
1079
1080 static int
1081 getint ()
1082 {
1083   intmax_t ret;
1084
1085   ret = getintmax ();
1086
1087   if (ret > INT_MAX)
1088     {
1089       printf_erange (garglist->word->word);
1090       ret = INT_MAX;
1091     }
1092   else if (ret < INT_MIN)
1093     {
1094       printf_erange (garglist->word->word);
1095       ret = INT_MIN;
1096     }
1097
1098   return ((int)ret);
1099 }
1100
1101 static intmax_t
1102 getintmax ()
1103 {
1104   intmax_t ret;
1105   char *ep;
1106
1107   if (garglist == 0)
1108     return (0);
1109
1110   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
1111     return asciicode ();
1112
1113   errno = 0;
1114   ret = strtoimax (garglist->word->word, &ep, 0);
1115
1116   if (*ep)
1117     {
1118       sh_invalidnum (garglist->word->word);
1119       /* POSIX.2 says ``...a diagnostic message shall be written to standard
1120          error, and the utility shall not exit with a zero exit status, but
1121          shall continue processing any remaining operands and shall write the
1122          value accumulated at the time the error was detected to standard
1123          output.''  Yecch. */
1124 #if 0
1125       ret = 0;          /* return partially-converted value from strtoimax */
1126 #endif
1127       conversion_error = 1;
1128     }
1129   else if (errno == ERANGE)
1130     printf_erange (garglist->word->word);
1131
1132   garglist = garglist->next;
1133   return (ret);
1134 }
1135
1136 static uintmax_t
1137 getuintmax ()
1138 {
1139   uintmax_t ret;
1140   char *ep;
1141
1142   if (garglist == 0)
1143     return (0);
1144
1145   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
1146     return asciicode ();
1147
1148   errno = 0;
1149   ret = strtoumax (garglist->word->word, &ep, 0);
1150   
1151   if (*ep)
1152     {
1153       sh_invalidnum (garglist->word->word);
1154       /* Same POSIX.2 conversion error requirements as getintmax(). */
1155       ret = 0;
1156       conversion_error = 1;
1157     }
1158   else if (errno == ERANGE)
1159     printf_erange (garglist->word->word);
1160
1161   garglist = garglist->next;
1162   return (ret);
1163 }
1164
1165 static floatmax_t
1166 getfloatmax ()
1167 {
1168   floatmax_t ret;
1169   char *ep;
1170
1171   if (garglist == 0)
1172     return (0);
1173
1174   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
1175     return asciicode ();
1176
1177   errno = 0;
1178   ret = strtofltmax (garglist->word->word, &ep);
1179
1180   if (*ep)
1181     {
1182       sh_invalidnum (garglist->word->word);
1183       /* Same thing about POSIX.2 conversion error requirements. */
1184       ret = 0;
1185       conversion_error = 1;
1186     }
1187   else if (errno == ERANGE)
1188     printf_erange (garglist->word->word);
1189
1190   garglist = garglist->next;
1191   return (ret);
1192 }
1193
1194 /* NO check is needed for garglist here. */
1195 static intmax_t
1196 asciicode ()
1197 {
1198   register intmax_t ch;
1199 #if defined (HANDLE_MULTIBYTE)
1200   wchar_t wc;
1201   size_t mblength, slen;
1202 #endif
1203   DECLARE_MBSTATE;
1204
1205 #if defined (HANDLE_MULTIBYTE)
1206   slen = strlen (garglist->word->word+1);
1207   mblength = MBLEN (garglist->word->word+1, slen);
1208   if (mblength > 1)
1209     {
1210       mblength = mbtowc (&wc, garglist->word->word+1, slen);
1211       ch = wc;          /* XXX */
1212     }
1213   else
1214 #endif
1215     ch = (unsigned char)garglist->word->word[1];
1216
1217   garglist = garglist->next;
1218   return (ch);
1219 }
1220
1221 static SHELL_VAR *
1222 bind_printf_variable (name, value, flags)
1223      char *name;
1224      char *value;
1225      int flags;
1226 {
1227 #if defined (ARRAY_VARS)
1228   if (valid_array_reference (name) == 0)
1229     return (bind_variable (name, value, flags));
1230   else
1231     return (assign_array_element (name, value, flags));
1232 #else /* !ARRAY_VARS */
1233   return bind_variable (name, value, flags);
1234 #endif /* !ARRAY_VARS */
1235 }