diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-05-09 18:07:53 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-05-09 18:08:03 -0700 |
commit | fe0e6110261a2ccc742334699aa247b428348b82 (patch) | |
tree | 6a1919b551f3ce72f81b10cb7f42d35636d9bb1c | |
parent | 8dd2d0a8c2396144ec8616387751ae00ca5e2f54 (diff) |
various fixes and improvements to sscanf
-rw-r--r-- | src/library.js | 42 | ||||
-rwxr-xr-x | tests/runner.py | 15 |
2 files changed, 48 insertions, 9 deletions
diff --git a/src/library.js b/src/library.js index 290f71f2..f2f1a3cb 100644 --- a/src/library.js +++ b/src/library.js @@ -2244,6 +2244,15 @@ LibraryManager.library = { // TODO: Document. _scanString__deps: ['_isFloat'], _scanString: function(format, get, unget, varargs) { + if (!__scanString.whiteSpace) { + __scanString.whiteSpace = {}; + __scanString.whiteSpace[' '.charCodeAt(0)] = 1; + __scanString.whiteSpace['\t'.charCodeAt(0)] = 1; + __scanString.whiteSpace['\n'.charCodeAt(0)] = 1; + __scanString.whiteSpace[' '] = 1; + __scanString.whiteSpace['\t'] = 1; + __scanString.whiteSpace['\n'] = 1; + } // Supports %x, %4x, %d.%d, %s, %f, %lf. // TODO: Support all format specifiers. format = Pointer_stringify(format); @@ -2251,6 +2260,7 @@ LibraryManager.library = { var argsi = 0; var fields = 0; var argIndex = 0; + var next; for (var formatIndex = 0; formatIndex < format.length; formatIndex++) { if (next <= 0) return fields; var next = get(); @@ -2266,11 +2276,14 @@ LibraryManager.library = { if (formatIndex != maxSpecifierStart) { max_ = parseInt(format.slice(maxSpecifierStart, formatIndex), 10); } - // TODO: Handle type size modifier. var long_ = false; + var half = false; if (format[formatIndex] == 'l') { long_ = true; formatIndex++; + } else if (format[formatIndex] == 'h') { + half = true; + formatIndex++; } var type = format[formatIndex]; formatIndex++; @@ -2290,13 +2303,16 @@ LibraryManager.library = { buffer.pop(); unget(); } + unget(); + next = get(); } 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' && (next != ' '.charCodeAt(0) && next != '\t'.charCodeAt(0) && next != '\n'.charCodeAt(0))) && + if (!(next in __scanString.whiteSpace) && // stop on whitespace + ((type == 's' || + ((type === 'd' || type == 'u') && 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))))) && (formatIndex >= format.length || next !== format[formatIndex].charCodeAt(0))) { // Stop when we read something that is coming up buffer.push(String.fromCharCode(next)); next = get(); @@ -2311,8 +2327,12 @@ LibraryManager.library = { var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; argIndex += Runtime.getNativeFieldSize('void*'); switch (type) { - case 'd': - {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}} + case 'd': case 'u': + if (half) { + {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i16') }}}; + } else { + {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}}; + } break; case 'x': {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}} @@ -2332,6 +2352,12 @@ LibraryManager.library = { break; } fields++; + } else if (format[formatIndex] in __scanString.whiteSpace) { + while (next in __scanString.whiteSpace) { + next = get(); + if (next <= 0) return fields; // End of input. + } + unget(); } else { // Not a specifier. if (format[formatIndex].charCodeAt(0) !== next) { diff --git a/tests/runner.py b/tests/runner.py index ef779783..17acdbd9 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -3808,10 +3808,23 @@ at function.:blag printf("|%s|\n", buffy); sscanf("cheez somethingmoar\tyet more\n", "cheez %s", buffy); printf("|%s|\n", buffy); + + int numverts = -1; + printf("%d\n", sscanf(" numverts 1499\n", " numverts %d", &numverts)); // white space is the same, even if tab vs space + printf("%d\n", numverts); + + int index; + float u, v; + short start, count; + printf("%d\n", sscanf(" vert 87 ( 0.481565 0.059481 ) 0 1\n", " vert %d ( %f %f ) %hu %hu", &index, &u, &v, &start, &count)); + printf("%d,%.6f,%.6f,%hu,%hu\n", index, u, v, start, count); + return 0; } ''' - self.do_run(src, 'en-us : 2\nen-r : 99\nen : 3\n1.234567, 0.000000\n-3.0300\n|some|\n|something|\n|somethingmoar|') + self.do_run(src, 'en-us : 2\nen-r : 99\nen : 3\n1.234567, 0.000000\n-3.0300\n|some|\n|something|\n|somethingmoar|\n' + + '1\n1499\n' + + '5\n87,0.481565,0.059481,0,1\n') def test_sscanf_2(self): # doubles |