summaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
authorDenys Vlasenko2010-10-05 13:22:11 +0200
committerDenys Vlasenko2010-10-05 13:22:11 +0200
commitd527e0c81d2efe98f258f1e1516a0e9cbe879154 (patch)
tree104ab5a0d550ea60151891848581880c0eca7e9a /editors
parent5b3430017895001e134b6c37a0ea4d2c082ba209 (diff)
downloadbusybox-d527e0c81d2efe98f258f1e1516a0e9cbe879154.zip
busybox-d527e0c81d2efe98f258f1e1516a0e9cbe879154.tar.gz
awk: 00.123 is not a octal constant; neither is 009.123. fixing this
function old new delta my_strtod 80 113 +33 Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'editors')
-rw-r--r--editors/awk.c48
1 files changed, 40 insertions, 8 deletions
diff --git a/editors/awk.c b/editors/awk.c
index f47d1ab..d9f9e0f 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -17,10 +17,14 @@
/* If you comment out one of these below, it will be #defined later
* to perform debug printfs to stderr: */
#define debug_printf_walker(...) do {} while (0)
+#define debug_printf_eval(...) do {} while (0)
#ifndef debug_printf_walker
# define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__))
#endif
+#ifndef debug_printf_eval
+# define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__))
+#endif
@@ -700,14 +704,27 @@ static ALWAYS_INLINE int isalnum_(int c)
static double my_strtod(char **pp)
{
+ char *cp = *pp;
#if ENABLE_DESKTOP
- if ((*pp)[0] == '0'
- && ((((*pp)[1] | 0x20) == 'x') || isdigit((*pp)[1]))
- ) {
- return strtoull(*pp, pp, 0);
+ if (cp[0] == '0') {
+ /* Might be hex or octal integer: 0x123abc or 07777 */
+ char c = (cp[1] | 0x20);
+ if (c == 'x' || isdigit(cp[1])) {
+ unsigned long long ull = strtoull(cp, pp, 0);
+ if (c == 'x')
+ return ull;
+ c = **pp;
+ if (!isdigit(c) && c != '.')
+ return ull;
+ /* else: it may be a floating number. Examples:
+ * 009.123 (*pp points to '9')
+ * 000.123 (*pp points to '.')
+ * fall through to strtod.
+ */
+ }
}
#endif
- return strtod(*pp, pp);
+ return strtod(cp, pp);
}
/* -------- working with variables (set/get/copy/etc) -------- */
@@ -817,17 +834,21 @@ static double getvar_i(var *v)
v->number = 0;
s = v->string;
if (s && *s) {
+ debug_printf_eval("getvar_i: '%s'->", s);
v->number = my_strtod(&s);
+ debug_printf_eval("%f (s:'%s')\n", v->number, s);
if (v->type & VF_USER) {
s = skip_spaces(s);
if (*s != '\0')
v->type &= ~VF_USER;
}
} else {
+ debug_printf_eval("getvar_i: '%s'->zero\n", s);
v->type &= ~VF_USER;
}
v->type |= VF_CACHED;
}
+ debug_printf_eval("getvar_i: %f\n", v->number);
return v->number;
}
@@ -849,6 +870,7 @@ static var *copyvar(var *dest, const var *src)
if (dest != src) {
clrvar(dest);
dest->type |= (src->type & ~(VF_DONTTOUCH | VF_FSTR));
+ debug_printf_eval("copyvar: number:%f string:'%s'\n", src->number, src->string);
dest->number = src->number;
if (src->string)
dest->string = xstrdup(src->string);
@@ -2347,18 +2369,25 @@ static var *evaluate(node *op, var *res)
opn = (opinfo & OPNMASK);
g_lineno = op->lineno;
op1 = op->l.n;
+ debug_printf_eval("opinfo:%08x opn:%08x XC:%x\n", opinfo, opn, XC(opinfo & OPCLSMASK));
/* execute inevitable things */
if (opinfo & OF_RES1)
L.v = evaluate(op1, v1);
if (opinfo & OF_RES2)
R.v = evaluate(op->r.n, v1+1);
- if (opinfo & OF_STR1)
+ if (opinfo & OF_STR1) {
L.s = getvar_s(L.v);
- if (opinfo & OF_STR2)
+ debug_printf_eval("L.s:'%s'\n", L.s);
+ }
+ if (opinfo & OF_STR2) {
R.s = getvar_s(R.v);
- if (opinfo & OF_NUM1)
+ debug_printf_eval("R.s:'%s'\n", R.s);
+ }
+ if (opinfo & OF_NUM1) {
L_d = getvar_i(L.v);
+ debug_printf_eval("L_d:%f\n", L_d);
+ }
switch (XC(opinfo & OPCLSMASK)) {
@@ -2526,6 +2555,7 @@ static var *evaluate(node *op, var *res)
break;
case XC( OC_MOVE ):
+ debug_printf_eval("MOVE\n");
/* if source is a temporary string, jusk relink it to dest */
//Disabled: if R.v is numeric but happens to have cached R.v->string,
//then L.v ends up being a string, which is wrong
@@ -2777,6 +2807,7 @@ static var *evaluate(node *op, var *res)
case XC( OC_BINARY ):
case XC( OC_REPLACE ): {
double R_d = getvar_i(R.v);
+ debug_printf_eval("BINARY/REPLACE: R_d:%f opn:%c\n", R_d, opn);
switch (opn) {
case '+':
L_d += R_d;
@@ -2805,6 +2836,7 @@ static var *evaluate(node *op, var *res)
L_d -= (int)(L_d / R_d) * R_d;
break;
}
+ debug_printf_eval("BINARY/REPLACE result:%f\n", L_d);
res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : L.v, L_d);
break;
}