From b80f6443b6b7b620c7272664c66ecb0b120a0998 Mon Sep 17 00:00:00 2001
From: Jari Aalto <jari.aalto@cante.net>
Date: Tue, 27 Jul 2004 13:29:18 +0000
Subject: Imported from ../bash-3.0.tar.gz.

---
 builtins/printf.def | 56 +++++++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 25 deletions(-)

(limited to 'builtins/printf.def')

diff --git a/builtins/printf.def b/builtins/printf.def
index 8821ecb..9b377a9 100644
--- a/builtins/printf.def
+++ b/builtins/printf.def
@@ -1,7 +1,7 @@
 This file is printf.def, from which is created printf.c.
 It implements the builtin "printf" in Bash.
 
-Copyright (C) 1997-2002 Free Software Foundation, Inc.
+Copyright (C) 1997-2003 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -55,6 +55,7 @@ $END
 #endif
 
 #include "../bashansi.h"
+#include "../bashintl.h"
 
 #include "../shell.h"
 #include "stdc.h"
@@ -105,7 +106,7 @@ extern int errno;
 
 static void printf_erange __P((char *));
 static void printstr __P((char *, char *, int, int, int));
-static int tescape __P((char *, int, char *, int *));
+static int tescape __P((char *, char *, int *));
 static char *bexpand __P((char *, int, int *, int *));
 static char *mklong __P((char *, char *, size_t));
 static int getchr __P((void));
@@ -114,7 +115,7 @@ static int  getint __P((void));
 static intmax_t getintmax __P((void));
 static uintmax_t getuintmax __P((void));
 
-#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD
+#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
 typedef long double floatmax_t;
 #  define FLOATMAX_CONV	"L"
 #  define strtofltmax	strtold
@@ -182,13 +183,12 @@ printf_builtin (list)
 	  precision = fieldwidth = 0;
 	  have_fieldwidth = have_precision = 0;
 
-
 	  if (*fmt == '\\')
 	    {
 	      fmt++;
-	      /* A NULL fourth argument to tescape means to not do special
-		 processing for \c. */
-	      fmt += tescape (fmt, 1, &nextch, (int *)NULL);
+	      /* A NULL third argument to tescape means to bypass the
+		 special processing for arguments to %b. */
+	      fmt += tescape (fmt, &nextch, (int *)NULL);
 	      putchar (nextch);
 	      fmt--;	/* for loop will increment it for us again */
 	      continue;
@@ -246,7 +246,7 @@ printf_builtin (list)
 	    
 	  if (*fmt == 0)
 	    {
-	      builtin_error ("`%s': missing format character", start);
+	      builtin_error (_("`%s': missing format character"), start);
 	      PRETURN (EXECUTION_FAILURE);
 	    }
 
@@ -405,7 +405,7 @@ printf_builtin (list)
 	    /* We don't output unrecognized format characters; we print an
 	       error message and return a failure exit status. */
 	    default:
-	      builtin_error ("`%c': invalid format character", convch);
+	      builtin_error (_("`%c': invalid format character"), convch);
 	      PRETURN (EXECUTION_FAILURE);
 	    }
 
@@ -531,6 +531,7 @@ printstr (fmt, string, len, fieldwidth, precision)
   
 /* Convert STRING by expanding the escape sequences specified by the
    POSIX standard for printf's `%b' format string.  If SAWC is non-null,
+   perform the processing appropriate for %b arguments.  In particular,
    recognize `\c' and use that as a string terminator.  If we see \c, set
    *SAWC to 1 before returning.  LEN is the length of STRING. */
 
@@ -540,11 +541,10 @@ printstr (fmt, string, len, fieldwidth, precision)
    value.  *SAWC is set to 1 if the escape sequence was \c, since that means
    to short-circuit the rest of the processing.  If SAWC is null, we don't
    do the \c short-circuiting, and \c is treated as an unrecognized escape
-   sequence.  */
+   sequence; we also bypass the other processing specific to %b arguments.  */
 static int
-tescape (estart, trans_squote, cp, sawc)
+tescape (estart, cp, sawc)
      char *estart;
-     int trans_squote;
      char *cp;
      int *sawc;
 {
@@ -576,14 +576,13 @@ tescape (estart, trans_squote, cp, sawc)
 
       case 'v': *cp = '\v'; break;
 
-      /* %b octal constants are `\0' followed by one, two, or three
-	 octal digits... */
-      case '0':
-      /* but, as an extension, the other echo-like octal escape
-	 sequences are supported as well. */
-      case '1': case '2': case '3': case '4':
-      case '5': case '6': case '7':
-	for (temp = 2+(c=='0'), evalue = c - '0'; ISOCTAL (*p) && temp--; p++)
+      /* The octal escape sequences are `\0' followed by up to three octal
+	 digits (if SAWC), or `\' followed by up to three octal digits (if
+	 !SAWC).  As an extension, we allow the latter form even if SAWC. */
+      case '0': case '1': case '2': case '3':
+      case '4': case '5': case '6': case '7':
+	evalue = OCTVALUE (c);
+	for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
 	  evalue = (evalue * 8) + OCTVALUE (*p);
 	*cp = evalue & 0xFF;
 	break;
@@ -591,11 +590,15 @@ tescape (estart, trans_squote, cp, sawc)
       /* And, as another extension, we allow \xNNN, where each N is a
 	 hex digit. */
       case 'x':
+#if 0
+	for (evalue = 0; ISXDIGIT ((unsigned char)*p); p++)
+#else
 	for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
+#endif
 	  evalue = (evalue * 16) + HEXVALUE (*p);
-	if (temp == 2)
+	if (p == estart + 1)
 	  {
-	    builtin_error ("missing hex digit for \\x");
+	    builtin_error (_("missing hex digit for \\x"));
 	    *cp = '\\';
 	    return 0;
 	  }
@@ -606,8 +609,11 @@ tescape (estart, trans_squote, cp, sawc)
 	*cp = c;
 	break;
 
-      case '\'':	/* TRANS_SQUOTE != 0 means \' -> ' */
-	if (trans_squote)
+      /* SAWC == 0 means that \', \", and \? are recognized as escape
+	 sequences, though the only processing performed is backslash
+	 removal. */
+      case '\'': case '"': case '?':
+	if (!sawc)
 	  *cp = c;
 	else
 	  {
@@ -657,7 +663,7 @@ bexpand (string, len, sawc, lenp)
 	  continue;
 	}
       temp = 0;
-      s += tescape (s, 0, &c, &temp);
+      s += tescape (s, &c, &temp);
       if (temp)
 	{
 	  if (sawc)
-- 
cgit v1.2.3

