aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSoeren Balko <Soeren.Balko@gmail.com>2013-05-25 12:20:14 +1000
committerAlon Zakai <alonzakai@gmail.com>2013-05-29 10:59:41 -0700
commit662da70e4e673b1611ed6587ece4e638bdf2b2ab (patch)
treee864e84517e10bd8fbad9648a3edcff8fd459db1
parente7016ba189980e52e8f490853e532ca9c1d4cefe (diff)
This fixes various strtoll/strtol issues, including tests
-rw-r--r--src/library.js29
-rwxr-xr-xtests/runner.py198
2 files changed, 221 insertions, 6 deletions
diff --git a/src/library.js b/src/library.js
index 00852630..e65754ba 100644
--- a/src/library.js
+++ b/src/library.js
@@ -3918,7 +3918,14 @@ LibraryManager.library = {
str++;
}
}
- }
+ } else if (finalBase==16) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
+ if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
+ {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
+ str += 2;
+ }
+ }
+ }
if (!finalBase) finalBase = 10;
// Get digits.
@@ -3969,13 +3976,14 @@ LibraryManager.library = {
#if USE_TYPED_ARRAYS == 2
_parseInt64__deps: ['isspace', '__setErrNo', '$ERRNO_CODES', function() { Types.preciseI64MathUsed = 1 }],
_parseInt64: function(str, endptr, base, min, max, unsign) {
- var start = str;
+ var isNegative = false;
// Skip space.
while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++;
-
+
// Check for a plus/minus sign.
if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('-') }}}) {
str++;
+ isNegative = true;
} else if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('+') }}}) {
str++;
}
@@ -3991,12 +3999,19 @@ LibraryManager.library = {
str += 2;
} else {
finalBase = 8;
- str++;
ok = true; // we saw an initial zero, perhaps the entire thing is just "0"
}
}
- }
+ } else if (finalBase==16) {
+ if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
+ if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
+ {{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
+ str += 2;
+ }
+ }
+ }
if (!finalBase) finalBase = 10;
+ start = str;
// Get digits.
var chr;
@@ -4009,6 +4024,7 @@ LibraryManager.library = {
ok = true;
}
}
+
if (!ok) {
___setErrNo(ERRNO_CODES.EINVAL);
{{{ makeStructuralReturn(['0', '0']) }}};
@@ -4020,7 +4036,8 @@ LibraryManager.library = {
}
try {
- i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign);
+ var numberString = isNegative ? '-'+Pointer_stringify(start, str - start) : Pointer_stringify(start, str - start);
+ i64Math.fromString(numberString, finalBase, min, max, unsign);
} catch(e) {
___setErrNo(ERRNO_CODES.ERANGE); // not quite correct
}
diff --git a/tests/runner.py b/tests/runner.py
index 827f1f5b..be8a49e5 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -4532,6 +4532,204 @@ The current type of b is: 9
self.do_run(src, '*1*', force_c=True)
+ def test_strtoll_hex(self):
+ # tests strtoll for hex strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "0x4 -0x3A +0xDEADBEEF";
+ char *end_char;
+
+ // undefined base
+ long long int l1 = strtoll(STRING, &end_char, 0);
+ long long int l2 = strtoll(end_char, &end_char, 0);
+ long long int l3 = strtoll(end_char, NULL, 0);
+
+ // defined base
+ long long int l4 = strtoll(STRING, &end_char, 16);
+ long long int l5 = strtoll(end_char, &end_char, 16);
+ long long int l6 = strtoll(end_char, NULL, 16);
+
+ printf("%d%d%d%d%d%d\n", l1==0x4, l2==-0x3a, l3==0xdeadbeef, l4==0x4, l5==-0x3a, l6==0xdeadbeef);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111111')
+
+ def test_strtoll_dec(self):
+ # tests strtoll for decimal strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "4 -38 +4711";
+ char *end_char;
+
+ // undefined base
+ long long int l1 = strtoll(STRING, &end_char, 0);
+ long long int l2 = strtoll(end_char, &end_char, 0);
+ long long int l3 = strtoll(end_char, NULL, 0);
+
+ // defined base
+ long long int l4 = strtoll(STRING, &end_char, 10);
+ long long int l5 = strtoll(end_char, &end_char, 10);
+ long long int l6 = strtoll(end_char, NULL, 10);
+
+ printf("%d%d%d%d%d%d\n", l1==4, l2==-38, l3==4711, l4==4, l5==-38, l6==4711);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111111')
+
+ def test_strtoll_bin(self):
+ # tests strtoll for binary strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "1 -101 +1011";
+ char *end_char;
+
+ // defined base
+ long long int l4 = strtoll(STRING, &end_char, 2);
+ long long int l5 = strtoll(end_char, &end_char, 2);
+ long long int l6 = strtoll(end_char, NULL, 2);
+
+ printf("%d%d%d\n", l4==1, l5==-5, l6==11);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111')
+
+ def test_strtoll_oct(self):
+ # tests strtoll for decimal strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "0 -035 +04711";
+ char *end_char;
+
+ // undefined base
+ long long int l1 = strtoll(STRING, &end_char, 0);
+ long long int l2 = strtoll(end_char, &end_char, 0);
+ long long int l3 = strtoll(end_char, NULL, 0);
+
+ // defined base
+ long long int l4 = strtoll(STRING, &end_char, 8);
+ long long int l5 = strtoll(end_char, &end_char, 8);
+ long long int l6 = strtoll(end_char, NULL, 8);
+
+ printf("%d%d%d%d%d%d\n", l1==0, l2==-29, l3==2505, l4==0, l5==-29, l6==2505);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111111')
+
+ def test_strtol_hex(self):
+ # tests strtoll for hex strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "0x4 -0x3A +0xDEAD";
+ char *end_char;
+
+ // undefined base
+ long l1 = strtol(STRING, &end_char, 0);
+ long l2 = strtol(end_char, &end_char, 0);
+ long l3 = strtol(end_char, NULL, 0);
+
+ // defined base
+ long l4 = strtol(STRING, &end_char, 16);
+ long l5 = strtol(end_char, &end_char, 16);
+ long l6 = strtol(end_char, NULL, 16);
+
+ printf("%d%d%d%d%d%d\n", l1==0x4, l2==-0x3a, l3==0xdead, l4==0x4, l5==-0x3a, l6==0xdead);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111111')
+
+ def test_strtol_dec(self):
+ # tests strtoll for decimal strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "4 -38 +4711";
+ char *end_char;
+
+ // undefined base
+ long l1 = strtol(STRING, &end_char, 0);
+ long l2 = strtol(end_char, &end_char, 0);
+ long l3 = strtol(end_char, NULL, 0);
+
+ // defined base
+ long l4 = strtol(STRING, &end_char, 10);
+ long l5 = strtol(end_char, &end_char, 10);
+ long l6 = strtol(end_char, NULL, 10);
+
+ printf("%d%d%d%d%d%d\n", l1==4, l2==-38, l3==4711, l4==4, l5==-38, l6==4711);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111111')
+
+ def test_strtol_bin(self):
+ # tests strtoll for binary strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "1 -101 +1011";
+ char *end_char;
+
+ // defined base
+ long l4 = strtol(STRING, &end_char, 2);
+ long l5 = strtol(end_char, &end_char, 2);
+ long l6 = strtol(end_char, NULL, 2);
+
+ printf("%d%d%d\n", l4==1, l5==-5, l6==11);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111')
+
+ def test_strtol_oct(self):
+ # tests strtoll for decimal strings (0x...)
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ const char *STRING = "0 -035 +04711";
+ char *end_char;
+
+ // undefined base
+ long l1 = strtol(STRING, &end_char, 0);
+ long l2 = strtol(end_char, &end_char, 0);
+ long l3 = strtol(end_char, NULL, 0);
+
+ // defined base
+ long l4 = strtol(STRING, &end_char, 8);
+ long l5 = strtol(end_char, &end_char, 8);
+ long l6 = strtol(end_char, NULL, 8);
+
+ printf("%d%d%d%d%d%d\n", l1==0, l2==-29, l3==2505, l4==0, l5==-29, l6==2505);
+ return 0;
+ }
+ '''
+ self.do_run(src, '111111')
+
def test_atexit(self):
# Confirms they are called in reverse order
src = r'''