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