]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - builtins/printf.def
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / builtins / printf.def
index f0b45904accb39dbe89adfe96781e517dd7ca72f..1d406080a046e8ca62202f914b8fcc1ccac54287 100644 (file)
@@ -88,13 +88,13 @@ static char *getstr __P((void));
 static int  getint __P((void));
 static int getlong __P((long *));
 static int getulong __P((unsigned long *));
-static double getdouble __P((void));
+static int getdouble __P((double *));
 static int asciicode __P((void));
 
 static WORD_LIST *garglist;
 static int retval;
 
-extern char *backslash_quote ();
+extern char *sh_backslash_quote ();
 
 int
 printf_builtin (list)
@@ -255,7 +255,7 @@ printf_builtin (list)
                char *p, *xp;
 
                p = getstr ();
-               xp = backslash_quote (p);
+               xp = sh_backslash_quote (p);
                if (xp)
                  {
                    /* Use printstr to get fieldwidth and precision right. */
@@ -307,7 +307,8 @@ printf_builtin (list)
              {
                double p;
 
-               p = getdouble ();
+               if (getdouble (&p))
+                 PRETURN (EXECUTION_FAILURE);
                PF(start, p);
                break;
              }
@@ -471,7 +472,8 @@ tescape (estart, trans_squote, cp, sawc)
 
       case 'b': *cp = '\b'; break;
 
-      case 'e': *cp = '\033'; break;   /* ESC -- non-ANSI */
+      case 'e':
+      case 'E': *cp = '\033'; break;   /* ESC -- non-ANSI */
 
       case 'f': *cp = '\f'; break;
 
@@ -484,7 +486,7 @@ tescape (estart, trans_squote, cp, sawc)
       case 'v': *cp = '\v'; break;
 
       /* %b octal constants are `\0' followed by one, two, or three
-         octal digits... */
+        octal digits... */
       case '0':
        for (temp = 3, evalue = 0; isoctal (*p) && temp--; p++)
          evalue = (evalue * 8) + OCTVALUE (*p);
@@ -638,8 +640,13 @@ getint ()
 
   if (ret > INT_MAX)
     {
-      builtin_error ("%s: %s", garglist->word->word, strerror(ERANGE));
-      return (0);
+      builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+      ret = INT_MAX;
+    }
+  else if (ret < INT_MIN)
+    {
+      builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+      ret = INT_MIN;
     }
 
   return ((int)ret);
@@ -676,10 +683,7 @@ getlong (lp)
       return (1);
     }
   else if (errno == ERANGE)
-    {
-      builtin_error ("%s: %s", garglist->word->word, strerror(ERANGE));
-      return (1);
-    }
+    builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
 
   *lp = ret;
   garglist = garglist->next;
@@ -714,31 +718,45 @@ getulong (ulp)
       return (1);
     }
   else if (errno == ERANGE)
-    {
-      builtin_error ("%s: %s", garglist->word->word, strerror(ERANGE));
-      return (1);
-    }
+    builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
 
   *ulp = ret;
   garglist = garglist->next;
   return (0);
 }
 
-static double
-getdouble ()
+static int
+getdouble (dp)
+     double *dp;
 {
   double ret;
+  char *ep;
 
   if (garglist == 0)
-    return ((double)0);
+    {
+      *dp = (double)0;
+      return (0);
+    }
 
   if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
-    return ((double)asciicode ());
+    {
+      *dp = (double)asciicode ();
+      return (0);
+    }
 
-  /* This should use strtod if it is available. */
-  ret = atof (garglist->word->word);
+  errno = 0;
+  ret = strtod (garglist->word->word, &ep);
+  if (*ep)
+    {
+      builtin_error ("%s: invalid number", garglist->word->word);
+      return (1);
+    }
+  else if (errno == ERANGE)
+    builtin_error ("warning: %s: %s", garglist->word->word, strerror(ERANGE));
+
+  *dp = ret;
   garglist = garglist->next;
-  return (ret);
+  return (0);
 }
 
 /* NO check is needed for garglist here. */