gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash server/action.cpp server/action.h ./Chang...


From: Michael Carlson
Subject: [Gnash-commit] gnash server/action.cpp server/action.h ./Chang...
Date: Thu, 09 Feb 2006 09:19:52 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Branch:         
Changes by:     Michael Carlson <address@hidden>        06/02/09 09:19:52

Modified files:
        server         : action.cpp action.h 
        .              : ChangeLog 
        testsuite/actionscript.all: Global.as 

Log message:
        Implement all of _global.parseInt, _global.isNan, _global.isFinite
        Also add as_value::is_finite() for internal use
        Add a few, and fix up the parseInt test cases

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/action.cpp.diff?tr1=1.32&tr2=1.33&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/server/action.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/ChangeLog.diff?tr1=1.108&tr2=1.109&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/gnash/gnash/testsuite/actionscript.all/Global.as.diff?tr1=1.3&tr2=1.4&r1=text&r2=text

Patches:
Index: gnash/ChangeLog
diff -u gnash/ChangeLog:1.108 gnash/ChangeLog:1.109
--- gnash/ChangeLog:1.108       Thu Feb  9 02:33:53 2006
+++ gnash/ChangeLog     Thu Feb  9 09:19:51 2006
@@ -1,3 +1,10 @@
+2006-02-09 Michael Carlson <address@hidden>
+
+       * server/action.cpp: implement _global.parseInt for all cases
+       Also implement _global.isNan, _global.isFinite
+       * server/action.h: add as_value::is_finite() for internal use
+       * testsuite/actionscript.all: add and fix up parseint test cases
+
 2006-02-08  Rob Savoye  <address@hidden>
 
        * Makefile.am: Rearrange directories for SUBDIRS and
Index: gnash/server/action.cpp
diff -u gnash/server/action.cpp:1.32 gnash/server/action.cpp:1.33
--- gnash/server/action.cpp:1.32        Thu Feb  9 02:33:53 2006
+++ gnash/server/action.cpp     Thu Feb  9 09:19:51 2006
@@ -102,7 +102,7 @@
 //
 // Number.toString() -- takes an optional arg that specifies the base
 //
-// parseInt(), parseFloat()
+// parseFloat()
 //
 // Boolean() type cast
 //
@@ -1041,18 +1041,104 @@
                fn.result->set_as_object_interface(new_obj);
        }
 
+       void as_global_isnan(const fn_call& fn)
+       {
+               assert(fn.nargs == 1);
+
+               fn.result->set_bool(fn.arg(0).is_nan());
+       }
+
+       void as_global_isfinite(const fn_call& fn)
+       {
+               assert(fn.nargs == 1);
+
+               fn.result->set_bool(!fn.arg(0).is_finite());
+       }
+
        void    as_global_parseint(const fn_call& fn)
        {
-               if (fn.nargs == 1)
+               assert(fn.nargs == 2 || fn.nargs == 1);
+
+               // Make sure our arguments are the correct type
+               fn.arg(0).convert_to_string();
+
+               if (fn.nargs > 1)
+                       fn.arg(1).convert_to_number();
+
+               // Set up some variables
+               const std::string digits = 
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+               char *input = new char[strlen(fn.arg(0).to_string())+1];
+               strcpy(input,fn.arg(0).to_string());
+               int base, result = 0, i;
+               bool bNegative;
+
+               // Skip leading whitespace
+               while (0 != isblank(input[0]))
+                       input++;
+
+               if (input[0] == '-')
                {
-                       // We're supposed to parse a string to an int, so let's 
make sure we have a string first                
-                       fn.arg(0).convert_to_string();
+                       bNegative = true;
+                       input++;
+               }
+               else
+                       bNegative = false;
 
-                       // Now return the parsed string
-                       fn.result->set_int(int(fn.arg(0).to_number()));
+               // Convert the string to uppercase
+               for (i=0;i<int(strlen(input));i++)
+                       input[i] = toupper(input[i]);
+
+               // if we were sent a second argument, that's our base
+               if (fn.nargs > 1)
+               {
+                       base = int(fn.arg(1).to_number());
+               }
+               // if the string starts with "0x" then a hex digit
+               else if (strlen(input) > 2 && input[0] == '0' && input[1] == 'X'
+                       && (isdigit(input[2]) || (input[2] >= 'A' && input[2] 
<= 'F')))
+               {
+                       base = 16;      // the base is 16
+                       input = input + 2; // skip the leading "0x"
+               }
+               // if the string starts with "0" then an octal digit
+               else if (strlen(input) > 1 && input[0] == '0' &&
+                       (input[1] >= '0' && input[1] <= '7'))
+               {
+                       base = 8;
+                       input++; // skip the leading '0'
                }
                else
-                       IF_VERBOSE_ACTION(log_error("Error: parseint was sent 
the wrong number of arguments (%d)\n",fn.nargs));
+                       // default base is 10
+                       base = 10;
+
+               assert (base >= 2 && base <= 36);
+
+               int numdigits = 0;
+
+               // Start at the beginning, see how many valid digits we have
+               // in the base we're dealing with
+               while (numdigits < int(strlen(input)) 
+                       && int(digits.find(input[numdigits])) < base
+                       && digits.find(input[numdigits]) != std::string::npos)
+                       numdigits++;
+
+               // If we didn't get any digits, we should return NaN
+               if (numdigits == 0)
+               {
+                       fn.result->set_nan();
+                       return;
+               }
+
+               for (i=0;i<numdigits;i++)
+               {
+                       result += digits.find(input[i])*int(pow(base,numdigits 
- i - 1));
+               }
+
+               if (bNegative)
+                       result = -result;
+
+               // Now return the parsed string
+               fn.result->set_int(result);
        }
 
        void    as_global_assetpropflags(const fn_call& fn)
@@ -1229,6 +1315,10 @@
                        s_global->set_member("ASSetPropFlags", 
as_global_assetpropflags);
                        // parseInt
                        s_global->set_member("parseInt", as_global_parseint);
+                       // isNan
+                       s_global->set_member("isNan", as_global_isnan);
+                       // isFinite
+                       s_global->set_member("isFinite", as_global_isfinite);
 
                        math_init();
                        key_init();
Index: gnash/server/action.h
diff -u gnash/server/action.h:1.11 gnash/server/action.h:1.12
--- gnash/server/action.h:1.11  Tue Feb  7 03:08:45 2006
+++ gnash/server/action.h       Thu Feb  9 09:19:51 2006
@@ -434,6 +434,7 @@
                void    set_double(double val) { drop_refs(); m_type = NUMBER; 
m_number_value = val; }
                void    set_bool(bool val) { drop_refs(); m_type = BOOLEAN; 
m_boolean_value = val; }
                void    set_int(int val) { set_double(val); }
+               void    set_nan() { double x = 0.0; set_double(x/x); }
 
                /// Make this value an as_object_interface.
                /// Internally adds a reference to the ref-counted 
as_object_interface.
@@ -461,6 +462,7 @@
 
                bool    is_nan() const { return (m_type == NUMBER && 
isnan(m_number_value)); }
                bool    is_inf() const { return (m_type == NUMBER && 
isinf(m_number_value)); }
+               bool is_finite() const { return (m_type == NUMBER && 
isfinite(m_number_value)); }
 
                bool    operator==(const as_value& v) const;
                bool    operator!=(const as_value& v) const;
Index: gnash/testsuite/actionscript.all/Global.as
diff -u gnash/testsuite/actionscript.all/Global.as:1.3 
gnash/testsuite/actionscript.all/Global.as:1.4
--- gnash/testsuite/actionscript.all/Global.as:1.3      Thu Feb  9 00:37:25 2006
+++ gnash/testsuite/actionscript.all/Global.as  Thu Feb  9 09:19:51 2006
@@ -31,8 +31,19 @@
 check ( parseInt('65') == 65 );
 check ( parseInt('-1234') == -1234 );
 check ( parseInt('-1.234') == -1 );
+// Test parseint with hex
+check ( parseInt('             0x111') == 273 );
+// Test parseint with octal
+check ( parseInt('   0352') == 234 );
+// Test parseint with 36 base
+check ( parseInt('2GA',36) == (10+16*36+2*36*36) );
+// Test parseint with base 17 - the 'H' is not part of base 17, only the first 
two digits are valid
+check ( parseInt('FGH',17) == (16+17*15) );
+check ( parseInt('513x51') == 513 );
+check ( isNan(parseInt('a1023')) );
 check ( isNaN(parseInt('zero')) );
-check ( !isFinite(parseInt('none')) );
+// parseInt returns NaN (which is different from infinity)
+check ( isFinite(parseInt('none')) );
 
 // All %NN must become the corresponding ascii char
 check ( unescape('%3A%2F%3F%3D%26') == ':/?=&' );




reply via email to

[Prev in Thread] Current Thread [Next in Thread]