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