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