1
0
Fork 0

string.scanf(): return elements in vector given as argument; function

only returns success (0: no match, 1: extensible match, 2: safe match)
This commit is contained in:
mfranz 2008-09-29 10:06:16 +00:00
parent 9f8e759f36
commit df90d69de9
2 changed files with 35 additions and 26 deletions

View file

@ -1,7 +1,7 @@
var listener = nil; var listener = nil;
var cmd = nil; var cmd = nil;
var data = nil; var data = nil;
var trans = { 356: '<', 357: '^', 358: '>', 359: '_' }; var translate = { 356: '<', 357: '^', 358: '>', 359: '_' };
var start = func { var start = func {
@ -18,6 +18,7 @@ var start = func {
var stop = func { var stop = func {
removelistener(listener); removelistener(listener);
listener = nil;
gui.popdown(); gui.popdown();
} }
@ -31,8 +32,8 @@ var handle_key = func(key) {
cmd = substr(cmd, 0, size(cmd) - 1); cmd = substr(cmd, 0, size(cmd) - 1);
} elsif (key == `\n` or key == `\r`) { } elsif (key == `\n` or key == `\r`) {
mode = 2; mode = 2;
} elsif (contains(trans, key)) { } elsif (contains(translate, key)) {
cmd ~= trans[key]; cmd ~= translate[key];
} elsif (!string.isprint(key)) { } elsif (!string.isprint(key)) {
return 0; return 0;
} else { } else {
@ -43,10 +44,10 @@ var handle_key = func(key) {
var bindings = []; var bindings = [];
if (size(cmd)) { if (size(cmd)) {
foreach (var e; data) { foreach (var e; data) {
var r = string.scanf(cmd, e[0]); var match = string.scanf(cmd, e[0], __multikey.arg = []);
if (r != nil and r[0]) { if (match) {
__multikey.arg = size(r) > 1 ? subvec(r, 1) : []; desc = e[1].getNode("desc", 1).getValue() or "";
desc = call(sprintf, [e[1].getNode("desc", 1).getValue() or ""] ~ __multikey.arg); desc = call(sprintf, [desc] ~ __multikey.arg);
bindings = e[1].getChildren("binding"); bindings = e[1].getChildren("binding");
if (e[1].getNode("no-exit") != nil) { if (e[1].getNode("no-exit") != nil) {
cmd = substr(cmd, 0, size(cmd) - 1); cmd = substr(cmd, 0, size(cmd) - 1);

View file

@ -232,12 +232,13 @@ replace = func(str, old, new) {
## ##
# Simple scanf function. Takes an input string and a pattern # Simple scanf function. Takes an input string, a pattern, and a
# and returns a vector containing success value and found elements. # vector. It returns 0 if the format didn't match, and appends
# all found elements to the given vector.
# #
# var r = string.scanf("comm3freq123.456", "comm%dfreq%f"); # var r = string.scanf("comm3freq123.456", "comm%ufreq%f", var result = []);
# #
# The resulting vector is [1, 3, 123.456]. # The result vector will be set to [3, 123.456].
# #
var Scan = { var Scan = {
new : func(s) {{ str: s, pos: 0, parents: [Scan] }}, new : func(s) {{ str: s, pos: 0, parents: [Scan] }},
@ -253,12 +254,12 @@ var Scan = {
}; };
var scanf = func(str, format) { var scanf = func(test, format, result) {
if (find("%", format) < 0) if (find("%", format) < 0)
return cmp(str, format) ? nil : [2]; return cmp(test, format) ? 0 : 2;
var result = [0]; var success = 0;
var str = Scan.new(str); var str = Scan.new(test);
var format = Scan.new(format); var format = Scan.new(format);
while (1) { while (1) {
@ -267,12 +268,12 @@ var scanf = func(str, format) {
break; break;
} elsif (f == `%`) { } elsif (f == `%`) {
result[0] = 1; # unsafe match success = 1; # unsafe match
f = format.getc(); f = format.getc();
if (f == nil) if (f == nil)
die("trailing %"); die("scanf: trailing % in format");
if (f == `%` and str.getc() != `%`) if (f == `%` and str.getc() != `%`)
return nil; return 0;
if (isdigit(f)) { if (isdigit(f)) {
var fnum = f - `0`; var fnum = f - `0`;
@ -291,7 +292,7 @@ var scanf = func(str, format) {
prefix = 1; prefix = 1;
} elsif (c == `-`) { } elsif (c == `-`) {
if (f == `u`) if (f == `u`)
return nil; return 0;
(prefix, sign) = (1, -1); (prefix, sign) = (1, -1);
} else { } else {
str.ungetc(); str.ungetc();
@ -302,7 +303,7 @@ var scanf = func(str, format) {
while ((var c = str.getc()) != nil and (fnum -= 1)) { while ((var c = str.getc()) != nil and (fnum -= 1)) {
if (f != `f` and c == `.`) if (f != `f` and c == `.`)
break; break;
elsif (num(numstr ~ chr(c) ~ '0') != nil) elsif (num(numstr ~ chr(c) ~ '0') != nil) # append 0 to digest e/E
numstr ~= chr(c); numstr ~= chr(c);
else else
break; break;
@ -310,23 +311,30 @@ var scanf = func(str, format) {
if (c != nil) if (c != nil)
str.ungetc(); str.ungetc();
if (num(numstr) == nil) if (num(numstr) == nil)
return nil; return 0;
} else { } else {
die("scanf: bad format %" ~ chr(f)); die("scanf: bad format element %" ~ chr(f));
} }
if (!size(numstr) and prefix) if (!size(numstr) and prefix)
return nil; return 0;
append(result, sign * num(numstr)); append(result, sign * num(numstr));
} elsif (isspace(f)) {
while ((var c = str.getc()) != nil and isspace(c))
nil;
if (c != nil)
str.ungetc();
} elsif (f != (var c = str.getc())) { } elsif (f != (var c = str.getc())) {
return nil; return 0;
} else { } else {
result[0] = 2; # safe match sucess = 2; # safe match
} }
} }
return str.getc() == nil and format.getc() == nil ? result : nil; return str.getc() == nil and format.getc() == nil ? success : 0;
} }