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