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