71a7c00e02b801bea24b0d0d2f4846f19276e7f9
[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               if (vbsize == 0)
259                 vbuf = xmalloc (vbsize = 16);
260               vblen = 0;
261               if (vbuf)
262                 vbuf[0] = 0;
263             }
264           else
265             {
266               sh_invalidid (vname);
267               return (EX_USAGE);
268             }
269           break;
270         default:
271           builtin_usage ();
272           return (EX_USAGE);
273         }
274     }
275   list = loptend;       /* skip over possible `--' */
276
277   if (list == 0)
278     {
279       builtin_usage ();
280       return (EX_USAGE);
281     }
282
283   if (list->word->word == 0 || list->word->word[0] == '\0')
284     return (EXECUTION_SUCCESS);
285
286   format = list->word->word;
287   tw = 0;
288
289   garglist = list->next;
290
291   /* If the format string is empty after preprocessing, return immediately. */
292   if (format == 0 || *format == 0)
293     return (EXECUTION_SUCCESS);
294
295   terminate_immediately++;
296           
297   /* Basic algorithm is to scan the format string for conversion
298      specifications -- once one is found, find out if the field
299      width or precision is a '*'; if it is, gather up value.  Note,
300      format strings are reused as necessary to use up the provided
301      arguments, arguments of zero/null string are provided to use
302      up the format string. */
303   do
304     {
305       tw = 0;
306       /* find next format specification */
307       for (fmt = format; *fmt; fmt++)
308         {
309           precision = fieldwidth = 0;
310           have_fieldwidth = have_precision = 0;
311
312           if (*fmt == '\\')
313             {
314               fmt++;
315               /* A NULL third argument to tescape means to bypass the
316                  special processing for arguments to %b. */
317 #if defined (HANDLE_MULTIBYTE)
318               /* Accommodate possible use of \u or \U, which can result in
319                  multibyte characters */
320               memset (mbch, '\0', sizeof (mbch));
321               fmt += tescape (fmt, mbch, &mblen, (int *)NULL);
322               for (mbind = 0; mbind < mblen; mbind++)
323                 PC (mbch[mbind]);
324 #else
325               fmt += tescape (fmt, &nextch, (int *)NULL, (int *)NULL);
326               PC (nextch);
327 #endif
328               fmt--;    /* for loop will increment it for us again */
329               continue;
330             }
331
332           if (*fmt != '%')
333             {
334               PC (*fmt);
335               continue;
336             }
337
338           /* ASSERT(*fmt == '%') */
339           start = fmt++;
340
341           if (*fmt == '%')              /* %% prints a % */
342             {
343               PC ('%');
344               continue;
345             }
346
347           /* found format specification, skip to field width */
348           for (; *fmt && strchr(SKIP1, *fmt); ++fmt)
349             ;
350
351           /* Skip optional field width. */
352           if (*fmt == '*')
353             {
354               fmt++;
355               have_fieldwidth = 1;
356               fieldwidth = getint ();
357             }
358           else
359             while (DIGIT (*fmt))
360               fmt++;
361
362           /* Skip optional '.' and precision */
363           if (*fmt == '.')
364             {
365               ++fmt;
366               if (*fmt == '*')
367                 {
368                   fmt++;
369                   have_precision = 1;
370                   precision = getint ();
371                 }
372               else
373                 {
374                   /* Negative precisions are allowed but treated as if the
375                      precision were missing; I would like to allow a leading
376                      `+' in the precision number as an extension, but lots
377                      of asprintf/fprintf implementations get this wrong. */
378 #if 0
379                   if (*fmt == '-' || *fmt == '+')
380 #else
381                   if (*fmt == '-')
382 #endif
383                     fmt++;
384                   while (DIGIT (*fmt))
385                     fmt++;
386                 }
387             }
388
389           /* skip possible format modifiers */
390           modstart = fmt;
391           while (*fmt && strchr (LENMODS, *fmt))
392             fmt++;
393             
394           if (*fmt == 0)
395             {
396               builtin_error (_("`%s': missing format character"), start);
397               PRETURN (EXECUTION_FAILURE);
398             }
399
400           convch = *fmt;
401           thisch = modstart[0];
402           nextch = modstart[1];
403           modstart[0] = convch;
404           modstart[1] = '\0';
405
406           switch(convch)
407             {
408             case 'c':
409               {
410                 char p;
411
412                 p = getchr ();
413                 PF(start, p);
414                 break;
415               }
416
417             case 's':
418               {
419                 char *p;
420
421                 p = getstr ();
422                 PF(start, p);
423                 break;
424               }
425
426             case '(':
427               {
428                 char *timefmt, timebuf[128], *t;
429                 int n;
430                 intmax_t arg;
431                 time_t secs;
432                 struct tm *tm;
433
434                 modstart[1] = nextch;   /* restore char after left paren */
435                 timefmt = xmalloc (strlen (fmt) + 3);
436                 fmt++;  /* skip over left paren */
437                 for (t = timefmt, n = 1; *fmt; )
438                   {
439                     if (*fmt == '(')
440                       n++;
441                     else if (*fmt == ')')
442                       n--;
443                     if (n == 0)
444                       break;
445                     *t++ = *fmt++;
446                   }
447                 *t = '\0';
448                 if (*++fmt != 'T')
449                   {
450                     builtin_warning (_("`%c': invalid time format specification"), *fmt);
451                     fmt = start;
452                     free (timefmt);
453                     PC (*fmt);
454                     continue;
455                   }
456                 if (timefmt[0] == '\0')
457                   {
458                     timefmt[0] = '%';
459                     timefmt[1] = 'X';   /* locale-specific current time - should we use `+'? */
460                     timefmt[2] = '\0';
461                   }
462                 /* argument is seconds since the epoch with special -1 and -2 */
463                 arg = getintmax ();
464                 if (arg == -1)
465                   secs = NOW;           /* roughly date +%s */
466                 else if (arg == -2)
467                   secs = shell_start_time;      /* roughly $SECONDS */
468                 else
469                   secs = arg;
470 #if defined (HAVE_TZSET)
471                 sv_tz ("TZ");           /* XXX -- just make sure */
472 #endif
473                 tm = localtime (&secs);
474                 n = strftime (timebuf, sizeof (timebuf), timefmt, tm);
475                 free (timefmt);
476                 if (n == 0)
477                   timebuf[0] = '\0';
478                 else
479                   timebuf[sizeof(timebuf) - 1] = '\0';
480                 /* convert to %s format that preserves fieldwidth and precision */
481                 modstart[0] = 's';
482                 modstart[1] = '\0';
483                 n = printstr (start, timebuf, strlen (timebuf), fieldwidth, precision); /* XXX - %s for now */
484                 if (n < 0)
485                   {
486                     sh_wrerror ();
487                     clearerr (stdout);
488                     PRETURN (EXECUTION_FAILURE);
489                   }
490                 break;
491               }
492
493             case 'n':
494               {
495                 char *var;
496
497                 var = getstr ();
498                 if (var && *var)
499                   {
500                     if (legal_identifier (var))
501                       bind_var_to_int (var, tw);
502                     else
503                       {
504                         sh_invalidid (var);
505                         PRETURN (EXECUTION_FAILURE);
506                       }
507                   }
508                 break;
509               }
510
511             case 'b':           /* expand escapes in argument */
512               {
513                 char *p, *xp;
514                 int rlen, r;
515
516                 p = getstr ();
517                 ch = rlen = r = 0;
518                 xp = bexpand (p, strlen (p), &ch, &rlen);
519
520                 if (xp)
521                   {
522                     /* Have to use printstr because of possible NUL bytes
523                        in XP -- printf does not handle that well. */
524                     r = printstr (start, xp, rlen, fieldwidth, precision);
525                     if (r < 0)
526                       {
527                         sh_wrerror ();
528                         clearerr (stdout);
529                         retval = EXECUTION_FAILURE;
530                       }
531                     free (xp);
532                   }
533
534                 if (ch || r < 0)
535                   PRETURN (retval);
536                 break;
537               }
538
539             case 'q':           /* print with shell quoting */
540               {
541                 char *p, *xp;
542                 int r;
543
544                 r = 0;
545                 p = getstr ();
546                 if (p && *p == 0)       /* XXX - getstr never returns null */
547                   xp = savestring ("''");
548                 else if (ansic_shouldquote (p))
549                   xp = ansic_quote (p, 0, (int *)0);
550                 else
551                   xp = sh_backslash_quote (p);
552                 if (xp)
553                   {
554                     /* Use printstr to get fieldwidth and precision right. */
555                     r = printstr (start, xp, strlen (xp), fieldwidth, precision);
556                     if (r < 0)
557                       {
558                         sh_wrerror ();
559                         clearerr (stdout);
560                       }
561                     free (xp);
562                   }
563
564                 if (r < 0)
565                   PRETURN (EXECUTION_FAILURE);
566                 break;
567               }
568
569             case 'd':
570             case 'i':
571               {
572                 char *f;
573                 long p;
574                 intmax_t pp;
575
576                 p = pp = getintmax ();
577                 if (p != pp)
578                   {
579                     f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
580                     PF (f, pp);
581                   }
582                 else
583                   {
584                     /* Optimize the common case where the integer fits
585                        in "long".  This also works around some long
586                        long and/or intmax_t library bugs in the common
587                        case, e.g. glibc 2.2 x86.  */
588                     f = mklong (start, "l", 1);
589                     PF (f, p);
590                   }
591                 break;
592               }
593
594             case 'o':
595             case 'u':
596             case 'x':
597             case 'X':
598               {
599                 char *f;
600                 unsigned long p;
601                 uintmax_t pp;
602
603                 p = pp = getuintmax ();
604                 if (p != pp)
605                   {
606                     f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
607                     PF (f, pp);
608                   }
609                 else
610                   {
611                     f = mklong (start, "l", 1);
612                     PF (f, p);
613                   }
614                 break;
615               }
616
617             case 'e':
618             case 'E':
619             case 'f':
620             case 'F':
621             case 'g':
622             case 'G':
623 #if defined (HAVE_PRINTF_A_FORMAT)
624             case 'a':
625             case 'A':
626 #endif
627               {
628                 char *f;
629                 floatmax_t p;
630
631                 p = getfloatmax ();
632                 f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
633                 PF (f, p);
634                 break;
635               }
636
637             /* We don't output unrecognized format characters; we print an
638                error message and return a failure exit status. */
639             default:
640               builtin_error (_("`%c': invalid format character"), convch);
641               PRETURN (EXECUTION_FAILURE);
642             }
643
644           modstart[0] = thisch;
645           modstart[1] = nextch;
646         }
647
648       if (ferror (stdout))
649         {
650           sh_wrerror ();
651           clearerr (stdout);
652           PRETURN (EXECUTION_FAILURE);
653         }
654     }
655   while (garglist && garglist != list->next);
656
657   if (conversion_error)
658     retval = EXECUTION_FAILURE;
659
660   PRETURN (retval);
661 }
662
663 static void
664 printf_erange (s)
665      char *s;
666 {
667   builtin_error (_("warning: %s: %s"), s, strerror(ERANGE));
668 }
669
670 /* We duplicate a lot of what printf(3) does here. */
671 static int
672 printstr (fmt, string, len, fieldwidth, precision)
673      char *fmt;                 /* format */
674      char *string;              /* expanded string argument */
675      int len;                   /* length of expanded string */
676      int fieldwidth;            /* argument for width of `*' */
677      int precision;             /* argument for precision of `*' */
678 {
679 #if 0
680   char *s;
681 #endif
682   int padlen, nc, ljust, i;
683   int fw, pr;                   /* fieldwidth and precision */
684
685 #if 0
686   if (string == 0 || *string == '\0')
687 #else
688   if (string == 0 || len == 0)
689 #endif
690     return 0;
691
692 #if 0
693   s = fmt;
694 #endif
695   if (*fmt == '%')
696     fmt++;
697
698   ljust = fw = 0;
699   pr = -1;
700
701   /* skip flags */
702   while (strchr (SKIP1, *fmt))
703     {
704       if (*fmt == '-')
705         ljust = 1;
706       fmt++;
707     }
708
709   /* get fieldwidth, if present */
710   if (*fmt == '*')
711     {
712       fmt++;
713       fw = fieldwidth;
714       if (fw < 0)
715         {
716           fw = -fw;
717           ljust = 1;
718         }
719     }
720   else if (DIGIT (*fmt))
721     {
722       fw = *fmt++ - '0';
723       while (DIGIT (*fmt))
724         fw = (fw * 10) + (*fmt++ - '0');
725     }
726
727   /* get precision, if present */
728   if (*fmt == '.')
729     {
730       fmt++;
731       if (*fmt == '*')
732         {
733           fmt++;
734           pr = precision;
735         }
736       else if (DIGIT (*fmt))
737         {
738           pr = *fmt++ - '0';
739           while (DIGIT (*fmt))
740             pr = (pr * 10) + (*fmt++ - '0');
741         }
742     }
743
744 #if 0
745   /* If we remove this, get rid of `s'. */
746   if (*fmt != 'b' && *fmt != 'q')
747     {
748       internal_error ("format parsing problem: %s", s);
749       fw = pr = 0;
750     }
751 #endif
752
753   /* chars from string to print */
754   nc = (pr >= 0 && pr <= len) ? pr : len;
755
756   padlen = fw - nc;
757   if (padlen < 0)
758     padlen = 0;
759   if (ljust)
760     padlen = -padlen;
761
762   /* leading pad characters */
763   for (; padlen > 0; padlen--)
764     PC (' ');
765
766   /* output NC characters from STRING */
767   for (i = 0; i < nc; i++)
768     PC (string[i]);
769
770   /* output any necessary trailing padding */
771   for (; padlen < 0; padlen++)
772     PC (' ');
773
774   return (ferror (stdout) ? -1 : 0);
775 }
776   
777 /* Convert STRING by expanding the escape sequences specified by the
778    POSIX standard for printf's `%b' format string.  If SAWC is non-null,
779    perform the processing appropriate for %b arguments.  In particular,
780    recognize `\c' and use that as a string terminator.  If we see \c, set
781    *SAWC to 1 before returning.  LEN is the length of STRING. */
782
783 /* Translate a single backslash-escape sequence starting at ESTART (the
784    character after the backslash) and return the number of characters
785    consumed by the sequence.  CP is the place to return the translated
786    value.  *SAWC is set to 1 if the escape sequence was \c, since that means
787    to short-circuit the rest of the processing.  If SAWC is null, we don't
788    do the \c short-circuiting, and \c is treated as an unrecognized escape
789    sequence; we also bypass the other processing specific to %b arguments.  */
790 static int
791 tescape (estart, cp, lenp, sawc)
792      char *estart;
793      char *cp;
794      int *lenp, *sawc;
795 {
796   register char *p;
797   int temp, c, evalue;
798   unsigned long uvalue;
799
800   p = estart;
801   if (lenp)
802     *lenp = 1;
803
804   switch (c = *p++)
805     {
806 #if defined (__STDC__)
807       case 'a': *cp = '\a'; break;
808 #else
809       case 'a': *cp = '\007'; break;
810 #endif
811
812       case 'b': *cp = '\b'; break;
813
814       case 'e':
815       case 'E': *cp = '\033'; break;    /* ESC -- non-ANSI */
816
817       case 'f': *cp = '\f'; break;
818
819       case 'n': *cp = '\n'; break;
820
821       case 'r': *cp = '\r'; break;
822
823       case 't': *cp = '\t'; break;
824
825       case 'v': *cp = '\v'; break;
826
827       /* The octal escape sequences are `\0' followed by up to three octal
828          digits (if SAWC), or `\' followed by up to three octal digits (if
829          !SAWC).  As an extension, we allow the latter form even if SAWC. */
830       case '0': case '1': case '2': case '3':
831       case '4': case '5': case '6': case '7':
832         evalue = OCTVALUE (c);
833         for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
834           evalue = (evalue * 8) + OCTVALUE (*p);
835         *cp = evalue & 0xFF;
836         break;
837
838       /* And, as another extension, we allow \xNN, where each N is a
839          hex digit. */
840       case 'x':
841         for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
842           evalue = (evalue * 16) + HEXVALUE (*p);
843         if (p == estart + 1)
844           {
845             builtin_error (_("missing hex digit for \\x"));
846             *cp = '\\';
847             return 0;
848           }
849         *cp = evalue & 0xFF;
850         break;
851
852 #if defined (HANDLE_MULTIBYTE)
853       case 'u':
854       case 'U':
855         temp = (c == 'u') ? 4 : 8;      /* \uNNNN \UNNNNNNNN */
856         for (uvalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
857           uvalue = (uvalue * 16) + HEXVALUE (*p);
858         if (p == estart + 1)
859           {
860             builtin_error (_("missing unicode digit for \\%c"), c);
861             *cp = '\\';
862             return 0;
863           }
864         if (uvalue <= UCHAR_MAX)
865           *cp = uvalue;
866         else
867           {
868             temp = u32cconv (uvalue, cp);
869             cp[temp] = '\0';
870             if (lenp)
871               *lenp = temp;
872           }
873         break;
874 #endif
875         
876       case '\\':        /* \\ -> \ */
877         *cp = c;
878         break;
879
880       /* SAWC == 0 means that \', \", and \? are recognized as escape
881          sequences, though the only processing performed is backslash
882          removal. */
883       case '\'': case '"': case '?':
884         if (!sawc)
885           *cp = c;
886         else
887           {
888             *cp = '\\';
889             return 0;
890           }
891         break;
892
893       case 'c':
894         if (sawc)
895           {
896             *sawc = 1;
897             break;
898           }
899       /* other backslash escapes are passed through unaltered */
900       default:
901         *cp = '\\';
902         return 0;
903       }
904   return (p - estart);
905 }
906
907 static char *
908 bexpand (string, len, sawc, lenp)
909      char *string;
910      int len, *sawc, *lenp;
911 {
912   int temp;
913   char *ret, *r, *s, c;
914 #if defined (HANDLE_MULTIBYTE)
915   char mbch[25];
916   int mbind, mblen;
917 #endif
918
919   if (string == 0 || len == 0)
920     {
921       if (sawc)
922         *sawc = 0;
923       if (lenp)
924         *lenp = 0;
925       return ((char *)NULL);
926     }
927
928   ret = (char *)xmalloc (len + 1);
929   for (r = ret, s = string; s && *s; )
930     {
931       c = *s++;
932       if (c != '\\' || *s == '\0')
933         {
934           *r++ = c;
935           continue;
936         }
937       temp = 0;
938 #if defined (HANDLE_MULTIBYTE)
939       memset (mbch, '\0', sizeof (mbch));
940       s += tescape (s, mbch, &mblen, &temp);
941 #else
942       s += tescape (s, &c, (int *)NULL, &temp);
943 #endif
944       if (temp)
945         {
946           if (sawc)
947             *sawc = 1;
948           break;
949         }
950
951 #if defined (HANDLE_MULTIBYTE)
952       for (mbind = 0; mbind < mblen; mbind++)
953         *r++ = mbch[mbind];
954 #else
955       *r++ = c;
956 #endif      
957     }
958
959   *r = '\0';
960   if (lenp)
961     *lenp = r - ret;
962   return ret;
963 }
964
965 static char *
966 vbadd (buf, blen)
967      char *buf;
968      int blen;
969 {
970   size_t nlen;
971
972   nlen = vblen + blen + 1;
973   if (nlen >= vbsize)
974     {
975       vbsize = ((nlen + 63) >> 6) << 6;
976       vbuf = (char *)xrealloc (vbuf, vbsize);
977     }
978
979   if (blen == 1)
980     vbuf[vblen++] = buf[0];
981   else if (blen > 1)
982     {
983       FASTCOPY (buf, vbuf  + vblen, blen);
984       vblen += blen;
985     }
986   vbuf[vblen] = '\0';
987
988 #ifdef DEBUG
989   if  (strlen (vbuf) != vblen)
990     internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
991 #endif
992
993   return vbuf;
994 }
995
996 static int
997 #if defined (PREFER_STDARG)
998 vbprintf (const char *format, ...)
999 #else
1000 vbprintf (format, va_alist)
1001   const char *format;
1002   va_dcl
1003 #endif
1004 {
1005   va_list args;
1006   size_t nlen;
1007   int blen;
1008
1009   SH_VA_START (args, format);
1010   blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
1011   va_end (args);
1012
1013   nlen = vblen + blen + 1;
1014   if (nlen >= vbsize)
1015     {
1016       vbsize = ((nlen + 63) >> 6) << 6;
1017       vbuf = (char *)xrealloc (vbuf, vbsize);
1018       SH_VA_START (args, format);
1019       blen = vsnprintf (vbuf + vblen, vbsize - vblen, format, args);
1020       va_end (args);
1021     }
1022
1023   vblen += blen;
1024   vbuf[vblen] = '\0';
1025
1026 #ifdef DEBUG
1027   if  (strlen (vbuf) != vblen)
1028     internal_error  ("printf:vbadd: vblen (%d) != strlen (vbuf) (%d)", vblen, (int)strlen (vbuf));
1029 #endif
1030   
1031   return (blen);
1032 }
1033
1034 static char *
1035 mklong (str, modifiers, mlen)
1036      char *str;
1037      char *modifiers;
1038      size_t mlen;
1039 {
1040   size_t len, slen;
1041
1042   slen = strlen (str);
1043   len = slen + mlen + 1;
1044
1045   if (len > conv_bufsize)
1046     {
1047       conv_bufsize = (((len + 1023) >> 10) << 10);
1048       conv_buf = (char *)xrealloc (conv_buf, conv_bufsize);
1049     }
1050
1051   FASTCOPY (str, conv_buf, slen - 1);
1052   FASTCOPY (modifiers, conv_buf + slen - 1, mlen);
1053
1054   conv_buf[len - 2] = str[slen - 1];
1055   conv_buf[len - 1] = '\0';
1056   return (conv_buf);
1057 }
1058
1059 static int
1060 getchr ()
1061 {
1062   int ret;
1063
1064   if (garglist == 0)
1065     return ('\0');
1066
1067   ret = (int)garglist->word->word[0];
1068   garglist = garglist->next;
1069   return ret;
1070 }
1071
1072 static char *
1073 getstr ()
1074 {
1075   char *ret;
1076
1077   if (garglist == 0)
1078     return ("");
1079
1080   ret = garglist->word->word;
1081   garglist = garglist->next;
1082   return ret;
1083 }
1084
1085 static int
1086 getint ()
1087 {
1088   intmax_t ret;
1089
1090   ret = getintmax ();
1091
1092   if (ret > INT_MAX)
1093     {
1094       printf_erange (garglist->word->word);
1095       ret = INT_MAX;
1096     }
1097   else if (ret < INT_MIN)
1098     {
1099       printf_erange (garglist->word->word);
1100       ret = INT_MIN;
1101     }
1102
1103   return ((int)ret);
1104 }
1105
1106 static intmax_t
1107 getintmax ()
1108 {
1109   intmax_t ret;
1110   char *ep;
1111
1112   if (garglist == 0)
1113     return (0);
1114
1115   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
1116     return asciicode ();
1117
1118   errno = 0;
1119   ret = strtoimax (garglist->word->word, &ep, 0);
1120
1121   if (*ep)
1122     {
1123       sh_invalidnum (garglist->word->word);
1124       /* POSIX.2 says ``...a diagnostic message shall be written to standard
1125          error, and the utility shall not exit with a zero exit status, but
1126          shall continue processing any remaining operands and shall write the
1127          value accumulated at the time the error was detected to standard
1128          output.''  Yecch. */
1129 #if 0
1130       ret = 0;          /* return partially-converted value from strtoimax */
1131 #endif
1132       conversion_error = 1;
1133     }
1134   else if (errno == ERANGE)
1135     printf_erange (garglist->word->word);
1136
1137   garglist = garglist->next;
1138   return (ret);
1139 }
1140
1141 static uintmax_t
1142 getuintmax ()
1143 {
1144   uintmax_t ret;
1145   char *ep;
1146
1147   if (garglist == 0)
1148     return (0);
1149
1150   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
1151     return asciicode ();
1152
1153   errno = 0;
1154   ret = strtoumax (garglist->word->word, &ep, 0);
1155   
1156   if (*ep)
1157     {
1158       sh_invalidnum (garglist->word->word);
1159       /* Same POSIX.2 conversion error requirements as getintmax(). */
1160       ret = 0;
1161       conversion_error = 1;
1162     }
1163   else if (errno == ERANGE)
1164     printf_erange (garglist->word->word);
1165
1166   garglist = garglist->next;
1167   return (ret);
1168 }
1169
1170 static floatmax_t
1171 getfloatmax ()
1172 {
1173   floatmax_t ret;
1174   char *ep;
1175
1176   if (garglist == 0)
1177     return (0);
1178
1179   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
1180     return asciicode ();
1181
1182   errno = 0;
1183   ret = strtofltmax (garglist->word->word, &ep);
1184
1185   if (*ep)
1186     {
1187       sh_invalidnum (garglist->word->word);
1188       /* Same thing about POSIX.2 conversion error requirements. */
1189       ret = 0;
1190       conversion_error = 1;
1191     }
1192   else if (errno == ERANGE)
1193     printf_erange (garglist->word->word);
1194
1195   garglist = garglist->next;
1196   return (ret);
1197 }
1198
1199 /* NO check is needed for garglist here. */
1200 static intmax_t
1201 asciicode ()
1202 {
1203   register intmax_t ch;
1204 #if defined (HANDLE_MULTIBYTE)
1205   wchar_t wc;
1206   size_t mblength, slen;
1207 #endif
1208   DECLARE_MBSTATE;
1209
1210 #if defined (HANDLE_MULTIBYTE)
1211   slen = strlen (garglist->word->word+1);
1212   mblength = MBLEN (garglist->word->word+1, slen);
1213   if (mblength > 1)
1214     {
1215       mblength = mbtowc (&wc, garglist->word->word+1, slen);
1216       ch = wc;          /* XXX */
1217     }
1218   else
1219 #endif
1220     ch = (unsigned char)garglist->word->word[1];
1221
1222   garglist = garglist->next;
1223   return (ch);
1224 }
1225
1226 static SHELL_VAR *
1227 bind_printf_variable (name, value, flags)
1228      char *name;
1229      char *value;
1230      int flags;
1231 {
1232 #if defined (ARRAY_VARS)
1233   if (valid_array_reference (name) == 0)
1234     return (bind_variable (name, value, flags));
1235   else
1236     return (assign_array_element (name, value, flags));
1237 #else /* !ARRAY_VARS */
1238   return bind_variable (name, value, flags);
1239 #endif /* !ARRAY_VARS */
1240 }