diff options
Diffstat (limited to 'builtins/printf.def')
| -rw-r--r-- | builtins/printf.def | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/builtins/printf.def b/builtins/printf.def index f0b45904..1d406080 100644 --- a/builtins/printf.def +++ b/builtins/printf.def @@ -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. */ |
