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