diff --git a/src/lib/getopts.rs b/src/lib/getopts.rs index faf9d131e73e..bdcfbea3b287 100644 --- a/src/lib/getopts.rs +++ b/src/lib/getopts.rs @@ -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) }