[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog testsuite/actionscript.all/Glob...
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] gnash ChangeLog testsuite/actionscript.all/Glob... |
Date: |
Tue, 18 Mar 2008 22:47:39 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Benjamin Wolsey <bwy> 08/03/18 22:47:38
Modified files:
. : ChangeLog
testsuite/actionscript.all: Global.as
server/asobj : Global.cpp
Log message:
* testsuite/actionscript.all/Global.as: add more parseInt tests
showing
some errors with hexadecimal parsing.
* server/asobj/Global.cpp: rewrite parseInt to deal with most
of the
main cases correctly.
There are some wacky cases with long strings and high bases that
still aren't right. I haven't worked out whether there's some
sense in the madness yet.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5967&r2=1.5968
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Global.as?cvsroot=gnash&r1=1.46&r2=1.47
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Global.cpp?cvsroot=gnash&r1=1.96&r2=1.97
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5967
retrieving revision 1.5968
diff -u -b -r1.5967 -r1.5968
--- ChangeLog 18 Mar 2008 18:36:21 -0000 1.5967
+++ ChangeLog 18 Mar 2008 22:47:37 -0000 1.5968
@@ -1,5 +1,12 @@
2008-03-18 Benjamin Wolsey <address@hidden>
+ * testsuite/actionscript.all/Global.as: add more parseInt tests showing
+ some errors with hexadecimal parsing.
+ * server/asobj/Global.cpp: rewrite parseInt to deal with most of the
+ main cases correctly.
+
+2008-03-18 Benjamin Wolsey <address@hidden>
+
* testsuite/swfdec/swfdec_gnash_tester: don't use fromdos. It's
not always available and seems to be unnecessary.
Index: testsuite/actionscript.all/Global.as
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Global.as,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -b -r1.46 -r1.47
--- testsuite/actionscript.all/Global.as 18 Mar 2008 14:01:00 -0000
1.46
+++ testsuite/actionscript.all/Global.as 18 Mar 2008 22:47:38 -0000
1.47
@@ -22,7 +22,7 @@
// execute it like this gnash -1 -r 0 -v out.swf
-rcsid="$Id: Global.as,v 1.46 2008/03/18 14:01:00 bwy Exp $";
+rcsid="$Id: Global.as,v 1.47 2008/03/18 22:47:38 bwy Exp $";
#include "check.as"
#if OUTPUT_VERSION > 5
@@ -63,16 +63,31 @@
check_equals(typeof(ASSetNativeAccessor), 'function');
// Test parseInt
-check ( parseInt('45b') == 45 );
-check ( parseInt('65') == 65 );
-check ( parseInt('-1234') == -1234 );
-check ( parseInt('-1.234') == -1 );
+check_equals ( parseInt('45b'), 45 );
+check_equals ( parseInt('65'), 65 );
+check_equals ( parseInt('-1234'), -1234 );
+check_equals ( parseInt('-1.234'), -1 );
+check_equals ( parseInt(' -1234'), -1234 );
+check_equals ( parseInt(' +12.34'), 12 );
+check_equals ( parseInt(" 234"), 234 );
+check ( isNaN(parseInt('++3')));
+
// Test parseint with hex
+// No whitespace allowed. Sign must come after0x
check ( parseInt('0x111') == 273 );
check ( isNaN(parseInt('0xw')));
+check ( isNaN(parseInt('-0x111')));
+check ( isNaN(parseInt('+0x111')));
+check ( parseInt(' 0x111') == 0 );
+check ( parseInt('0x-111') == -273 );
+check ( parseInt('0x+111') == 273 );
+check ( parseInt('0X-111') == -273 );
+check ( parseInt('0X+111') == 273 );
+
// Test parseint with octal
check_equals (parseInt('0352'), 234 );
check_equals (parseInt('-0352'), -234);
+check_equals (parseInt('+0352'), 234);
// Evidently only numbers with no whitespace in front and
// no digits higher than 7 are octal. These all decimal:
check_equals (parseInt('07658'), 7658);
@@ -96,6 +111,12 @@
o = {}; o.toString = function() { return "12"; };
check_equals (parseInt(o), 12);
+check(isNaN(parseInt("8589934592", 5)));
+
+// Er...
+xcheck_equals(parseInt("8589934592", 16), 573538780562);
+xcheck_equals(parseInt("800000000", 36), 22568879259648);
+
// It's not reliable to compare a double type with ==, so we'll give it a
// small range using >= and <=
check ( isNaN(parseFloat('test')) );
@@ -385,15 +406,15 @@
//------------------------------------------------------------
#if OUTPUT_VERSION == 5
- check_totals(98); // SWF5
+ check_totals(113); // SWF5
#else
# if OUTPUT_VERSION == 6
- check_totals(132); // SWF6
+ check_totals(147); // SWF6
# else
# if OUTPUT_VERSION == 7
- check_totals(114); // SWF7
+ check_totals(129); // SWF7
# else
- check_totals(101); // SWF8+
+ check_totals(116); // SWF8+
# endif
# endif
#endif
Index: server/asobj/Global.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Global.cpp,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- server/asobj/Global.cpp 6 Mar 2008 16:17:43 -0000 1.96
+++ server/asobj/Global.cpp 18 Mar 2008 22:47:38 -0000 1.97
@@ -187,6 +187,17 @@
return rv;
}
+// The second argument, if supplied, is the base.
+// If none is supplied, we have to work out the
+// base from the string. Decimal, octal and hexadecimal are
+// possible, according to the following rules:
+// 1. If the string starts with 0x or 0X, the number is hex.
+// 2. The 0x or 0X may be *followed* by '-' or '+' to indicate sign. A number
+// with no sign is positive.
+// 3. If the string starts with 0, -0 or +0 and contains only the characters
+// 0-7.
+// 4. If the string starts with *any* other sequence of characters, including
+// whitespace, it is decimal.
static as_value
as_global_parseint(const fn_call& fn)
{
@@ -202,32 +213,20 @@
log_aserror(_("%s has more than two arguments"), __FUNCTION__);
)
+ const std::string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
const std::string& expr = fn.arg(0).to_string();
- int base = 10;
- const std::string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- bool bNegative = false;
+ bool negative = false;
+ int base = 0;
std::string::const_iterator it = expr.begin();
- // Skip leading whitespace
- while(*it == ' ' || *it == '\n' || *it == '\t' || *it == '\r')
- {
- ++it;
- }
-
- // Is the first non-whitespace character a minus?
- if (*it == '-')
- {
- bNegative = true;
- ++it;
- }
// if we were sent a second argument, that's our base
if (fn.nargs > 1)
{
- // to_number returns a double. atoi() would be better
- base = (int)(fn.arg(1).to_number());
+ base = (fn.arg(1).to_int());
// Bases from 2 to 36 are valid, otherwise return NaN
if (base < 2 || base > 36)
@@ -236,48 +235,85 @@
rv.set_nan();
return rv;
}
-
}
-
- // If the string starts with '0x':
- else if (expr.end() - it >= 2 &&
- (*it == '0' && toupper(*(it + 1)) == 'X' ))
+ else
+ {
+ // Try hexadecimal first
+ if (expr.substr(0, 2) == "0x" || expr.substr(0, 2) == "0X")
{
- // the base is 16
base = 16;
- // Move to the digit after the 'x'
it += 2;
+
+ if (*it == '-')
+ {
+ negative = true;
+ it++;
+ }
+ else if (*it == '+')
+ {
+ it++;
}
+ }
+ // Either octal or decimal.
+ else if (*it == '0' || *it == '-' || *it == '+')
+ {
+
+ base = 8;
- // Octal if the string starts with "0" then an octal digit, but
- // *only* if there is no whitespace before it; in that case decimal.
- else if (it - expr.begin() == (bNegative ? 1 : 0))
- {
- if (expr.end() - it >= 2 &&
- *it == '0' && isdigit(*(it + 1)))
- {
- // And if there are any chars other than 0-7, it's *still* a
- // base 10 number...
- // At least we know where we are in the string, so can use
- // string methods.
- if (expr.find_first_not_of("01234567", (bNegative ? 1 : 0)) !=
+ // Check for negative and move to the next digit
+ if (*it == '-')
+ {
+ negative = true;
+ it++;
+ }
+ else if (*it == '+') it++;
+
+ if (*it != '0') base = 10;
+
+ // Check for expectional case "-0x" or "+0x", which
+ // return NaN
+ else if (std::toupper(*(it + 1)) == 'X')
+ {
+ as_value rv;
+ rv.set_nan();
+ return rv;
+ }
+
+ // Check from the current position for non-octal characters;
+ // it's decimal in that case.
+ else if (expr.find_first_not_of("01234567", it - expr.begin()) !=
std::string::npos)
{
base = 10;
}
- else base = 8;
+ }
+ // Everything else is decimal.
+ else
+ {
+ base = 10;
- // Point the iterator to the first digit after the '0'.
+ // Skip leading whitespace
+ while(*it == ' ' || *it == '\n' || *it == '\t' || *it == '\r')
+ {
++it;
-
+ }
+ if (*it == '-')
+ {
+ negative = true;
+ it++;
+ }
+ else if (*it == '+') it++;
}
}
+ // Now we have the base, parse the digits. The iterator should
+ // be pointing at the first digit.
+
// Check to see if the first digit is valid, otherwise
// return NaN.
int digit = digits.find(toupper(*it));
- if (digit >= base)
+ if (digit >= base || digit < 0)
{
as_value rv;
rv.set_nan();
@@ -298,7 +334,7 @@
++it;
}
- if (bNegative)
+ if (negative)
result = -result;
// Now return the parsed string as an integer.