stdlib: Port most of getopts over to interior vectors
This commit is contained in:
parent
3427a41272
commit
2e827eab24
@ -65,7 +65,7 @@ fn optmulti(str name) -> opt {
|
||||
|
||||
tag optval { val(str); given; }
|
||||
|
||||
type match = rec(vec[opt] opts, vec[mutable vec[optval]] vals, vec[str] free);
|
||||
type match = rec(opt[] opts, (optval[])[mutable] vals, vec[str] free);
|
||||
|
||||
fn is_arg(str arg) -> bool {
|
||||
ret str::byte_len(arg) > 1u && arg.(0) == '-' as u8;
|
||||
@ -78,9 +78,9 @@ fn name_str(name nm) -> str {
|
||||
};
|
||||
}
|
||||
|
||||
fn find_opt(vec[opt] opts, name nm) -> option::t[uint] {
|
||||
fn find_opt(&opt[] opts, name nm) -> option::t[uint] {
|
||||
auto i = 0u;
|
||||
auto l = vec::len[opt](opts);
|
||||
auto l = ivec::len[opt](opts);
|
||||
while (i < l) {
|
||||
if (opts.(i).name == nm) { ret some[uint](i); }
|
||||
i += 1u;
|
||||
@ -119,19 +119,31 @@ fn fail_str(fail_ f) -> str {
|
||||
tag result { success(match); failure(fail_); }
|
||||
|
||||
fn getopts(vec[str] args, vec[opt] opts) -> result {
|
||||
auto n_opts = vec::len[opt](opts);
|
||||
fn f(uint x) -> vec[optval] { ret vec::empty(); }
|
||||
auto vals = vec::init_fn_mut[vec[optval]](f, n_opts);
|
||||
// FIXME: Remove this vec->ivec conversion.
|
||||
auto args_ivec = ~[]; auto opts_ivec = ~[];
|
||||
for (str arg in args) { args_ivec += ~[arg]; }
|
||||
for (opt o in opts) { opts_ivec += ~[o]; }
|
||||
ret getopts_ivec(args_ivec, opts_ivec);
|
||||
}
|
||||
|
||||
fn getopts_ivec(&str[] args, &opt[] opts) -> result {
|
||||
auto n_opts = ivec::len[opt](opts);
|
||||
fn f(uint x) -> optval[] { ret ~[]; }
|
||||
auto vals = ivec::init_fn_mut[optval[]](f, n_opts);
|
||||
let vec[str] free = [];
|
||||
auto l = vec::len[str](args);
|
||||
auto l = ivec::len[str](args);
|
||||
auto i = 0u;
|
||||
while (i < l) {
|
||||
auto cur = args.(i);
|
||||
auto curlen = str::byte_len(cur);
|
||||
if (!is_arg(cur)) {
|
||||
vec::push[str](free, cur);
|
||||
free += [cur];
|
||||
} else if (str::eq(cur, "--")) {
|
||||
free += vec::slice[str](args, i + 1u, l);
|
||||
auto j = i + 1u;
|
||||
while (j < l) {
|
||||
free += [args.(j)];
|
||||
j += 1u;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
auto names;
|
||||
@ -140,19 +152,19 @@ fn getopts(vec[str] args, vec[opt] opts) -> result {
|
||||
auto tail = str::slice(cur, 2u, curlen);
|
||||
auto eq = str::index(tail, '=' as u8);
|
||||
if (eq == -1) {
|
||||
names = [long(tail)];
|
||||
names = ~[long(tail)];
|
||||
} else {
|
||||
names = [long(str::slice(tail, 0u, eq as uint))];
|
||||
names = ~[long(str::slice(tail, 0u, eq as uint))];
|
||||
i_arg =
|
||||
option::some[str](str::slice(tail, (eq as uint) + 1u,
|
||||
curlen - 2u));
|
||||
}
|
||||
} else {
|
||||
auto j = 1u;
|
||||
names = [];
|
||||
names = ~[];
|
||||
while (j < curlen) {
|
||||
auto range = str::char_range_at(cur, j);
|
||||
vec::push[name](names, short(range._0));
|
||||
names += ~[short(range._0)];
|
||||
j = range._1;
|
||||
}
|
||||
}
|
||||
@ -171,29 +183,27 @@ fn getopts(vec[str] args, vec[opt] opts) -> result {
|
||||
if (!option::is_none[str](i_arg)) {
|
||||
ret failure(unexpected_argument(name_str(nm)));
|
||||
}
|
||||
vec::push[optval](vals.(optid), given);
|
||||
vals.(optid) += ~[given];
|
||||
}
|
||||
case (maybe) {
|
||||
if (!option::is_none[str](i_arg)) {
|
||||
vec::push[optval](vals.(optid),
|
||||
val(option::get[str](i_arg)));
|
||||
} else if (name_pos < vec::len[name](names) ||
|
||||
vals.(optid) += ~[val(option::get(i_arg))];
|
||||
} else if (name_pos < ivec::len[name](names) ||
|
||||
i + 1u == l || is_arg(args.(i + 1u))) {
|
||||
vec::push[optval](vals.(optid), given);
|
||||
vals.(optid) += ~[given];
|
||||
} else {
|
||||
i += 1u;
|
||||
vec::push[optval](vals.(optid), val(args.(i)));
|
||||
vals.(optid) += ~[val(args.(i))];
|
||||
}
|
||||
}
|
||||
case (yes) {
|
||||
if (!option::is_none[str](i_arg)) {
|
||||
vec::push[optval](vals.(optid),
|
||||
val(option::get[str](i_arg)));
|
||||
vals.(optid) += ~[val(option::get[str](i_arg))];
|
||||
} else if (i + 1u == l) {
|
||||
ret failure(argument_missing(name_str(nm)));
|
||||
} else {
|
||||
i += 1u;
|
||||
vec::push[optval](vals.(optid), val(args.(i)));
|
||||
vals.(optid) += ~[val(args.(i))];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,7 +213,7 @@ fn getopts(vec[str] args, vec[opt] opts) -> result {
|
||||
}
|
||||
i = 0u;
|
||||
while (i < n_opts) {
|
||||
auto n = vec::len[optval](vals.(i));
|
||||
auto n = ivec::len[optval](vals.(i));
|
||||
auto occ = opts.(i).occur;
|
||||
if (occ == req) {
|
||||
if (n == 0u) {
|
||||
@ -220,7 +230,7 @@ fn getopts(vec[str] args, vec[opt] opts) -> result {
|
||||
ret success(rec(opts=opts, vals=vals, free=free));
|
||||
}
|
||||
|
||||
fn opt_vals(match m, str nm) -> vec[optval] {
|
||||
fn opt_vals(match m, str nm) -> optval[] {
|
||||
ret alt (find_opt(m.opts, mkname(nm))) {
|
||||
case (some(?id)) { m.vals.(id) }
|
||||
case (none) { log_err "No option '" + nm + "' defined."; fail }
|
||||
@ -230,7 +240,7 @@ fn opt_vals(match m, str nm) -> vec[optval] {
|
||||
fn opt_val(match m, str nm) -> optval { ret opt_vals(m, nm).(0); }
|
||||
|
||||
fn opt_present(match m, str nm) -> bool {
|
||||
ret vec::len[optval](opt_vals(m, nm)) > 0u;
|
||||
ret ivec::len[optval](opt_vals(m, nm)) > 0u;
|
||||
}
|
||||
|
||||
fn opt_str(match m, str nm) -> str {
|
||||
@ -240,14 +250,22 @@ fn opt_str(match m, str nm) -> str {
|
||||
fn opt_strs(match m, str nm) -> vec[str] {
|
||||
let vec[str] acc = [];
|
||||
for (optval v in opt_vals(m, nm)) {
|
||||
alt (v) { case (val(?s)) { vec::push[str](acc, s); } case (_) { } }
|
||||
alt (v) { case (val(?s)) { acc += [s]; } case (_) { } }
|
||||
}
|
||||
ret acc;
|
||||
}
|
||||
|
||||
fn opt_strs_ivec(match m, str nm) -> str[] {
|
||||
let str[] acc = ~[];
|
||||
for (optval v in opt_vals(m, nm)) {
|
||||
alt (v) { case (val(?s)) { acc += ~[s]; } case (_) { } }
|
||||
}
|
||||
ret acc;
|
||||
}
|
||||
|
||||
fn opt_maybe_str(match m, str nm) -> option::t[str] {
|
||||
auto vals = opt_vals(m, nm);
|
||||
if (vec::len[optval](vals) == 0u) { ret none[str]; }
|
||||
if (ivec::len[optval](vals) == 0u) { ret none[str]; }
|
||||
ret alt (vals.(0)) {
|
||||
case (val(?s)) { some[str](s) }
|
||||
case (_) { none[str] }
|
||||
@ -260,7 +278,7 @@ fn opt_maybe_str(match m, str nm) -> option::t[str] {
|
||||
/// present and an argument was provided.
|
||||
fn opt_default(match m, str nm, str def) -> option::t[str] {
|
||||
auto vals = opt_vals(m, nm);
|
||||
if (vec::len[optval](vals) == 0u) { ret none[str]; }
|
||||
if (ivec::len[optval](vals) == 0u) { ret none[str]; }
|
||||
ret alt (vals.(0)) {
|
||||
case (val(?s)) { some[str](s) }
|
||||
case (_) { some[str](def) }
|
||||
|
Loading…
Reference in New Issue
Block a user