Skip to content

Commit 556964b

Browse files
committed
This fixes various strtoll/strtol issues, including tests
1 parent ea8286b commit 556964b

File tree

2 files changed

+221
-6
lines changed

2 files changed

+221
-6
lines changed

src/library.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,7 +3918,14 @@ LibraryManager.library = {
39183918
str++;
39193919
}
39203920
}
3921-
}
3921+
} else if (finalBase==16) {
3922+
if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
3923+
if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
3924+
{{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
3925+
str += 2;
3926+
}
3927+
}
3928+
}
39223929
if (!finalBase) finalBase = 10;
39233930

39243931
// Get digits.
@@ -3969,13 +3976,14 @@ LibraryManager.library = {
39693976
#if USE_TYPED_ARRAYS == 2
39703977
_parseInt64__deps: ['isspace', '__setErrNo', '$ERRNO_CODES', function() { Types.preciseI64MathUsed = 1 }],
39713978
_parseInt64: function(str, endptr, base, min, max, unsign) {
3972-
var start = str;
3979+
var isNegative = false;
39733980
// Skip space.
39743981
while (_isspace({{{ makeGetValue('str', 0, 'i8') }}})) str++;
3975-
3982+
39763983
// Check for a plus/minus sign.
39773984
if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('-') }}}) {
39783985
str++;
3986+
isNegative = true;
39793987
} else if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('+') }}}) {
39803988
str++;
39813989
}
@@ -3991,12 +3999,19 @@ LibraryManager.library = {
39913999
str += 2;
39924000
} else {
39934001
finalBase = 8;
3994-
str++;
39954002
ok = true; // we saw an initial zero, perhaps the entire thing is just "0"
39964003
}
39974004
}
3998-
}
4005+
} else if (finalBase==16) {
4006+
if ({{{ makeGetValue('str', 0, 'i8') }}} == {{{ charCode('0') }}}) {
4007+
if ({{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('x') }}} ||
4008+
{{{ makeGetValue('str+1', 0, 'i8') }}} == {{{ charCode('X') }}}) {
4009+
str += 2;
4010+
}
4011+
}
4012+
}
39994013
if (!finalBase) finalBase = 10;
4014+
start = str;
40004015

40014016
// Get digits.
40024017
var chr;
@@ -4009,6 +4024,7 @@ LibraryManager.library = {
40094024
ok = true;
40104025
}
40114026
}
4027+
40124028
if (!ok) {
40134029
___setErrNo(ERRNO_CODES.EINVAL);
40144030
{{{ makeStructuralReturn(['0', '0']) }}};
@@ -4020,7 +4036,8 @@ LibraryManager.library = {
40204036
}
40214037

40224038
try {
4023-
i64Math.fromString(Pointer_stringify(start, str - start), finalBase, min, max, unsign);
4039+
var numberString = isNegative ? '-'+Pointer_stringify(start, str - start) : Pointer_stringify(start, str - start);
4040+
i64Math.fromString(numberString, finalBase, min, max, unsign);
40244041
} catch(e) {
40254042
___setErrNo(ERRNO_CODES.ERANGE); // not quite correct
40264043
}

tests/runner.py

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4532,6 +4532,204 @@ def test_stdlibs(self):
45324532

45334533
self.do_run(src, '*1*', force_c=True)
45344534

4535+
def test_strtoll_hex(self):
4536+
# tests strtoll for hex strings (0x...)
4537+
src = r'''
4538+
#include <stdio.h>
4539+
#include <stdlib.h>
4540+
4541+
int main() {
4542+
const char *STRING = "0x4 -0x3A +0xDEADBEEF";
4543+
char *end_char;
4544+
4545+
// undefined base
4546+
long long int l1 = strtoll(STRING, &end_char, 0);
4547+
long long int l2 = strtoll(end_char, &end_char, 0);
4548+
long long int l3 = strtoll(end_char, NULL, 0);
4549+
4550+
// defined base
4551+
long long int l4 = strtoll(STRING, &end_char, 16);
4552+
long long int l5 = strtoll(end_char, &end_char, 16);
4553+
long long int l6 = strtoll(end_char, NULL, 16);
4554+
4555+
printf("%d%d%d%d%d%d\n", l1==0x4, l2==-0x3a, l3==0xdeadbeef, l4==0x4, l5==-0x3a, l6==0xdeadbeef);
4556+
return 0;
4557+
}
4558+
'''
4559+
self.do_run(src, '111111')
4560+
4561+
def test_strtoll_dec(self):
4562+
# tests strtoll for decimal strings (0x...)
4563+
src = r'''
4564+
#include <stdio.h>
4565+
#include <stdlib.h>
4566+
4567+
int main() {
4568+
const char *STRING = "4 -38 +4711";
4569+
char *end_char;
4570+
4571+
// undefined base
4572+
long long int l1 = strtoll(STRING, &end_char, 0);
4573+
long long int l2 = strtoll(end_char, &end_char, 0);
4574+
long long int l3 = strtoll(end_char, NULL, 0);
4575+
4576+
// defined base
4577+
long long int l4 = strtoll(STRING, &end_char, 10);
4578+
long long int l5 = strtoll(end_char, &end_char, 10);
4579+
long long int l6 = strtoll(end_char, NULL, 10);
4580+
4581+
printf("%d%d%d%d%d%d\n", l1==4, l2==-38, l3==4711, l4==4, l5==-38, l6==4711);
4582+
return 0;
4583+
}
4584+
'''
4585+
self.do_run(src, '111111')
4586+
4587+
def test_strtoll_bin(self):
4588+
# tests strtoll for binary strings (0x...)
4589+
src = r'''
4590+
#include <stdio.h>
4591+
#include <stdlib.h>
4592+
4593+
int main() {
4594+
const char *STRING = "1 -101 +1011";
4595+
char *end_char;
4596+
4597+
// defined base
4598+
long long int l4 = strtoll(STRING, &end_char, 2);
4599+
long long int l5 = strtoll(end_char, &end_char, 2);
4600+
long long int l6 = strtoll(end_char, NULL, 2);
4601+
4602+
printf("%d%d%d\n", l4==1, l5==-5, l6==11);
4603+
return 0;
4604+
}
4605+
'''
4606+
self.do_run(src, '111')
4607+
4608+
def test_strtoll_oct(self):
4609+
# tests strtoll for decimal strings (0x...)
4610+
src = r'''
4611+
#include <stdio.h>
4612+
#include <stdlib.h>
4613+
4614+
int main() {
4615+
const char *STRING = "0 -035 +04711";
4616+
char *end_char;
4617+
4618+
// undefined base
4619+
long long int l1 = strtoll(STRING, &end_char, 0);
4620+
long long int l2 = strtoll(end_char, &end_char, 0);
4621+
long long int l3 = strtoll(end_char, NULL, 0);
4622+
4623+
// defined base
4624+
long long int l4 = strtoll(STRING, &end_char, 8);
4625+
long long int l5 = strtoll(end_char, &end_char, 8);
4626+
long long int l6 = strtoll(end_char, NULL, 8);
4627+
4628+
printf("%d%d%d%d%d%d\n", l1==0, l2==-29, l3==2505, l4==0, l5==-29, l6==2505);
4629+
return 0;
4630+
}
4631+
'''
4632+
self.do_run(src, '111111')
4633+
4634+
def test_strtol_hex(self):
4635+
# tests strtoll for hex strings (0x...)
4636+
src = r'''
4637+
#include <stdio.h>
4638+
#include <stdlib.h>
4639+
4640+
int main() {
4641+
const char *STRING = "0x4 -0x3A +0xDEAD";
4642+
char *end_char;
4643+
4644+
// undefined base
4645+
long l1 = strtol(STRING, &end_char, 0);
4646+
long l2 = strtol(end_char, &end_char, 0);
4647+
long l3 = strtol(end_char, NULL, 0);
4648+
4649+
// defined base
4650+
long l4 = strtol(STRING, &end_char, 16);
4651+
long l5 = strtol(end_char, &end_char, 16);
4652+
long l6 = strtol(end_char, NULL, 16);
4653+
4654+
printf("%d%d%d%d%d%d\n", l1==0x4, l2==-0x3a, l3==0xdead, l4==0x4, l5==-0x3a, l6==0xdead);
4655+
return 0;
4656+
}
4657+
'''
4658+
self.do_run(src, '111111')
4659+
4660+
def test_strtol_dec(self):
4661+
# tests strtoll for decimal strings (0x...)
4662+
src = r'''
4663+
#include <stdio.h>
4664+
#include <stdlib.h>
4665+
4666+
int main() {
4667+
const char *STRING = "4 -38 +4711";
4668+
char *end_char;
4669+
4670+
// undefined base
4671+
long l1 = strtol(STRING, &end_char, 0);
4672+
long l2 = strtol(end_char, &end_char, 0);
4673+
long l3 = strtol(end_char, NULL, 0);
4674+
4675+
// defined base
4676+
long l4 = strtol(STRING, &end_char, 10);
4677+
long l5 = strtol(end_char, &end_char, 10);
4678+
long l6 = strtol(end_char, NULL, 10);
4679+
4680+
printf("%d%d%d%d%d%d\n", l1==4, l2==-38, l3==4711, l4==4, l5==-38, l6==4711);
4681+
return 0;
4682+
}
4683+
'''
4684+
self.do_run(src, '111111')
4685+
4686+
def test_strtol_bin(self):
4687+
# tests strtoll for binary strings (0x...)
4688+
src = r'''
4689+
#include <stdio.h>
4690+
#include <stdlib.h>
4691+
4692+
int main() {
4693+
const char *STRING = "1 -101 +1011";
4694+
char *end_char;
4695+
4696+
// defined base
4697+
long l4 = strtol(STRING, &end_char, 2);
4698+
long l5 = strtol(end_char, &end_char, 2);
4699+
long l6 = strtol(end_char, NULL, 2);
4700+
4701+
printf("%d%d%d\n", l4==1, l5==-5, l6==11);
4702+
return 0;
4703+
}
4704+
'''
4705+
self.do_run(src, '111')
4706+
4707+
def test_strtol_oct(self):
4708+
# tests strtoll for decimal strings (0x...)
4709+
src = r'''
4710+
#include <stdio.h>
4711+
#include <stdlib.h>
4712+
4713+
int main() {
4714+
const char *STRING = "0 -035 +04711";
4715+
char *end_char;
4716+
4717+
// undefined base
4718+
long l1 = strtol(STRING, &end_char, 0);
4719+
long l2 = strtol(end_char, &end_char, 0);
4720+
long l3 = strtol(end_char, NULL, 0);
4721+
4722+
// defined base
4723+
long l4 = strtol(STRING, &end_char, 8);
4724+
long l5 = strtol(end_char, &end_char, 8);
4725+
long l6 = strtol(end_char, NULL, 8);
4726+
4727+
printf("%d%d%d%d%d%d\n", l1==0, l2==-29, l3==2505, l4==0, l5==-29, l6==2505);
4728+
return 0;
4729+
}
4730+
'''
4731+
self.do_run(src, '111111')
4732+
45354733
def test_atexit(self):
45364734
# Confirms they are called in reverse order
45374735
src = r'''

0 commit comments

Comments
 (0)