1
0
Fork 0

string.scanf(): more efficient and (more :) correct %f detection

This commit is contained in:
mfranz 2008-09-28 20:23:14 +00:00
parent 7458142f70
commit 3197bc3f24

View file

@ -274,49 +274,51 @@ var scanf = func(str, format) {
if (f == `%` and str.getc() != `%`) if (f == `%` and str.getc() != `%`)
return nil; return nil;
var fnum = nil;
if (isdigit(f)) { if (isdigit(f)) {
fnum = f - `0`; var fnum = f - `0`;
while ((f = format.getc()) != nil and isdigit(f)) while ((f = format.getc()) != nil and isdigit(f))
fnum = fnum * 10 + f - `0`; fnum = fnum * 10 + f - `0`;
} else {
var fnum = -2; # because we add one if !prefix
} }
var numstr = ""; var numstr = "";
var plus = 0; var prefix = 0;
if (f == `d` or f == `f`) { # int or float with optional minus var sign = 1;
if (f == `d` or f == `f` or f == `u`) {
var c = str.getc(); var c = str.getc();
if (c == `+`) if (c == `+`) {
plus = 1; prefix = 1;
elsif (c == `-`) } elsif (c == `-`) {
numstr = chr(c); if (f == `u`)
else return nil;
(prefix, sign) = (1, -1);
} else {
str.ungetc(); str.ungetc();
} }
if (f == `D` or f == `F` or f == `d` or f == `f`) { # integer part if (!prefix)
while ((var c = str.getc()) != nil and isdigit(c)) fnum += 1;
numstr ~= chr(c);
if (c != nil) while ((var c = str.getc()) != nil and (fnum -= 1)) {
str.ungetc(); if (f != `f` and c == `.`)
} break;
if (f == `f` or f == `F`) { # fractional part elsif (num(numstr ~ chr(c) ~ '0') != nil)
while ((var c = str.getc()) != nil) {
if (num(numstr ~ chr(c)) != nil)
numstr ~= chr(c); numstr ~= chr(c);
else else
break; break;
} }
if (c != nil) if (c != nil)
str.ungetc(); str.ungetc();
if (num(numstr) == nil)
return nil;
} else {
die("scanf: bad format %" ~ chr(f));
} }
if (!size(numstr) and plus or numstr == "-") if (!size(numstr) and prefix)
return nil; return nil;
if (fnum != nil and size(numstr) > fnum) append(result, sign * num(numstr));
for (var i = size(numstr) - fnum; i; i -= 1)
str.ungetc();
append(result, num(numstr));
} elsif (f != (var c = str.getc())) { } elsif (f != (var c = str.getc())) {
return nil; return nil;