aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library.js64
-rw-r--r--tests/runner.py86
2 files changed, 97 insertions, 53 deletions
diff --git a/src/library.js b/src/library.js
index 1971ab66..1534dc7e 100644
--- a/src/library.js
+++ b/src/library.js
@@ -2132,9 +2132,14 @@ LibraryManager.library = {
// stdio.h
// ==========================================================================
+ _isFloat: function(text) {
+ return !!(/^[+]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?$/.exec(text));
+ },
+
// TODO: Document.
+ _scanString__deps: ['_isFloat'],
_scanString: function(format, get, unget, varargs) {
- // Supports %x, %4x, %d.%d, %s.
+ // Supports %x, %4x, %d.%d, %s, %f, %lf.
// TODO: Support all format specifiers.
format = Pointer_stringify(format);
var formatIndex = 0;
@@ -2157,22 +2162,43 @@ LibraryManager.library = {
max_ = parseInt(format.slice(maxSpecifierStart, formatIndex), 10);
}
// TODO: Handle type size modifier.
+ var long_ = false;
+ if (format[formatIndex] == 'l') {
+ long_ = true;
+ formatIndex++;
+ }
var type = format[formatIndex];
formatIndex++;
var curr = 0;
var buffer = [];
- while ((curr < max_ || isNaN(max_)) && next > 0) {
- if ((type === 'd' && next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) ||
- (type === 'x' && (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0) ||
- next >= 'a'.charCodeAt(0) && next <= 'f'.charCodeAt(0) ||
- next >= 'A'.charCodeAt(0) && next <= 'F'.charCodeAt(0))) ||
- (type === 's') &&
- (formatIndex >= format.length || next !== format[formatIndex].charCodeAt(0))) { // Stop when we read something that is coming up
+ // Read characters according to the format. floats are trickier, they may be in an unfloat state in the middle, then be a valid float later
+ if (type == 'f') {
+ var last = -1;
+ while (next > 0) {
buffer.push(String.fromCharCode(next));
+ if (__isFloat(buffer.join(''))) {
+ last = buffer.length;
+ }
next = get();
- curr++;
- } else {
- break;
+ }
+ while (buffer.length > last) {
+ buffer.pop();
+ unget();
+ }
+ } else {
+ while ((curr < max_ || isNaN(max_)) && next > 0) {
+ if ((type === 'd' && next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0)) ||
+ (type === 'x' && (next >= '0'.charCodeAt(0) && next <= '9'.charCodeAt(0) ||
+ next >= 'a'.charCodeAt(0) && next <= 'f'.charCodeAt(0) ||
+ next >= 'A'.charCodeAt(0) && next <= 'F'.charCodeAt(0))) ||
+ (type === 's') &&
+ (formatIndex >= format.length || next !== format[formatIndex].charCodeAt(0))) { // Stop when we read something that is coming up
+ buffer.push(String.fromCharCode(next));
+ next = get();
+ curr++;
+ } else {
+ break;
+ }
}
}
if (buffer.length === 0) return 0; // Failure.
@@ -2186,6 +2212,13 @@ LibraryManager.library = {
case 'x':
{{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}}
break;
+ case 'f':
+ if (long_) {
+ {{{ makeSetValue('argPtr', 0, 'parseFloat(text)', 'double') }}}
+ } else {
+ {{{ makeSetValue('argPtr', 0, 'parseFloat(text)', 'float') }}}
+ }
+ break;
case 's':
var array = intArrayFromString(text);
for (var j = 0; j < array.length; j++) {
@@ -2215,7 +2248,7 @@ LibraryManager.library = {
// NOTE: Explicitly ignoring type safety. Otherwise this fails:
// int x = 4; printf("%c\n", (char)x);
var ret;
- if (type === 'float' || type === 'double') {
+ if (type === 'double') {
ret = {{{ makeGetValue('varargs', 'argIndex', 'double', undefined, undefined, true) }}};
#if I64_MODE == 1
} else if (type == 'i64') {
@@ -2224,6 +2257,7 @@ LibraryManager.library = {
ret = unSign(ret[0], 32) + unSign(ret[1], 32)*Math.pow(2, 32); // Unsigned in this notation. Signed later if needed. // XXX - loss of precision
#endif
} else {
+ type = 'i32'; // varargs are always i32, i64, or double
ret = {{{ makeGetValue('varargs', 'argIndex', 'i32', undefined, undefined, true) }}};
}
argIndex += Runtime.getNativeFieldSize(type);
@@ -2313,9 +2347,9 @@ LibraryManager.library = {
var nextNext = {{{ makeGetValue(0, 'textIndex+2', 'i8') }}};
if (nextNext == 'h'.charCodeAt(0)) {
textIndex++;
- argSize = 1; // char
+ argSize = 1; // char (actually i32 in varargs)
} else {
- argSize = 2; // short
+ argSize = 2; // short (actually i32 in varargs)
}
break;
case 'l':
@@ -2427,7 +2461,7 @@ LibraryManager.library = {
});
} else if (['f', 'F', 'e', 'E', 'g', 'G'].indexOf(String.fromCharCode(next)) != -1) {
// Float.
- var currArg = getNextArg(argSize === 4 ? 'float' : 'double');
+ var currArg = getNextArg('double');
var argText;
if (isNaN(currArg)) {
diff --git a/tests/runner.py b/tests/runner.py
index 7d5a9580..74fb5057 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -3007,45 +3007,55 @@ at function.:blag
self.do_run(src)
# Part 2: doubles (issue 148)
- return # TODO: Make the second part here work
- src = r'''
- #include <stdio.h>
+ if Settings.USE_TYPED_ARRAYS == 2:
+ for ftype in ['float', 'double']:
+ src = r'''
+ #include <stdio.h>
- int main(){
- char strval1[] = "1.2345678901";
- char strval2[] = "1.23456789e5";
- char strval3[] = "1.23456789E5";
- char strval4[] = "1.2345678e-5";
- char strval5[] = "1.2345678E-5";
- double dblval = 1.2345678901;
- double tstval;
-
- sscanf(strval1, "%lf", &tstval);
- if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
- else printf("Pass: %lf %lf\n", tstval, dblval);
-
- sscanf(strval2, "%lf", &tstval);
- dblval = 123456.789;
- if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
- else printf("Pass: %lf %lf\n", tstval, dblval);
-
- sscanf(strval3, "%lf", &tstval);
- dblval = 123456.789;
- if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
- else printf("Pass: %lf %lf\n", tstval, dblval);
-
- sscanf(strval4, "%lf", &tstval);
- dblval = 0.000012345678;
- if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
- else printf("Pass: %lf %lf\n", tstval, dblval);
-
- sscanf(strval5, "%lf", &tstval);
- dblval = 0.000012345678;
- if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
- else printf("Pass: %lf %lf\n", tstval, dblval);
- }
- '''
- self.do_run(src)
+ int main(){
+ char strval1[] = "1.2345678901";
+ char strval2[] = "1.23456789e5";
+ char strval3[] = "1.23456789E5";
+ char strval4[] = "1.2345678e-5";
+ char strval5[] = "1.2345678E-5";
+ double dblval = 1.2345678901;
+ double tstval;
+
+ sscanf(strval1, "%lf", &tstval);
+ if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
+ else printf("Pass: %lf %lf\n", tstval, dblval);
+
+ sscanf(strval2, "%lf", &tstval);
+ dblval = 123456.789;
+ if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
+ else printf("Pass: %lf %lf\n", tstval, dblval);
+
+ sscanf(strval3, "%lf", &tstval);
+ dblval = 123456.789;
+ if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
+ else printf("Pass: %lf %lf\n", tstval, dblval);
+
+ sscanf(strval4, "%lf", &tstval);
+ dblval = 0.000012345678;
+ if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
+ else printf("Pass: %lf %lf\n", tstval, dblval);
+
+ sscanf(strval5, "%lf", &tstval);
+ dblval = 0.000012345678;
+ if(dblval != tstval) printf("FAIL: Values are not equal: %lf %lf\n", dblval, tstval);
+ else printf("Pass: %lf %lf\n", tstval, dblval);
+
+ return 0;
+ }
+ '''
+ if ftype == 'float':
+ self.do_run(src.replace('%lf', '%f').replace('double', 'float'), '''Pass: 1.234568 1.234568
+Pass: 123456.789063 123456.789063
+Pass: 123456.789063 123456.789063
+Pass: 0.000012 0.000012
+Pass: 0.000012 0.000012''')
+ else:
+ self.do_run(src)
def test_langinfo(self):
src = open(path_from_root('tests', 'langinfo', 'test.c'), 'r').read()