diff options
| author | Graydon Hoare <[email protected]> | 2011-04-26 20:39:33 +0000 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2011-04-26 20:39:33 +0000 |
| commit | bc6e9815379e31ac42b4d9fd2b0e20f708c1cc1c (patch) | |
| tree | f9ccd0dac288b2751536a6e552ec8e094e2a6739 /src | |
| parent | Various bits of trans lint, nothing major. (diff) | |
| parent | rustc: Cap ridiculous type name sizes (diff) | |
| download | rust-bc6e9815379e31ac42b4d9fd2b0e20f708c1cc1c.tar.xz rust-bc6e9815379e31ac42b4d9fd2b0e20f708c1cc1c.zip | |
Merge branch 'master' of ssh://github.com/graydon/rust
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/driver/rustc.rs | 202 | ||||
| -rw-r--r-- | src/comp/middle/ty.rs | 4 | ||||
| -rw-r--r-- | src/lib/GetOpts.rs | 249 | ||||
| -rw-r--r-- | src/lib/Term.rs | 54 | ||||
| -rw-r--r-- | src/lib/_str.rs | 8 | ||||
| -rw-r--r-- | src/lib/std.rc | 2 |
6 files changed, 392 insertions, 127 deletions
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs index 890e69da..c321b3a0 100644 --- a/src/comp/driver/rustc.rs +++ b/src/comp/driver/rustc.rs @@ -20,6 +20,12 @@ import std._str; import std._vec; import std.io; +import std.GetOpts; +import std.GetOpts.optopt; +import std.GetOpts.optmulti; +import std.GetOpts.optflag; +import std.GetOpts.opt_present; + fn default_environment(session.session sess, str argv0, str input) -> eval.env { @@ -105,18 +111,18 @@ fn usage(session.session sess, str argv0) { options: -o <filename> write output to <filename> - -nowarn suppress wrong-compiler warning - -glue generate glue.bc file - -shared compile a shared-library crate - -pp pretty-print the input instead of compiling - -ls list the symbols defined by a crate file + --nowarn suppress wrong-compiler warning + --glue generate glue.bc file + --shared compile a shared-library crate + --pretty pretty-print the input instead of compiling + --ls list the symbols defined by a crate file -L <path> add a directory to the library search path - -noverify suppress LLVM verification step (slight speedup) - -parse-only parse only; do not compile, assemble, or link + --noverify suppress LLVM verification step (slight speedup) + --parse-only parse only; do not compile, assemble, or link -O optimize -S compile only; do not assemble or link -c compile and assemble, but do not link - -save-temps write intermediate files in addition to normal output + --save-temps write intermediate files in addition to normal output -h display this message\n\n"); } @@ -142,133 +148,81 @@ fn main(vec[str] args) { auto sess = session.session(target_crate_num, target_cfg, crate_cache, md, front.codemap.new_codemap()); - let option.t[str] input_file = none[str]; - let option.t[str] output_file = none[str]; - let vec[str] library_search_paths = vec(); - let bool do_warn = true; - let bool shared = false; - let bool pretty = false; - let bool ls = false; - auto ot = trans.output_type_bitcode; - let bool glue = false; - let bool verify = true; - let bool save_temps = false; + auto opts = vec(optflag("nowarn"), optflag("h"), optflag("glue"), + optflag("pretty"), optflag("ls"), optflag("parse-only"), + optflag("O"), optflag("shared"), optmulti("L"), + optflag("S"), optflag("c"), optopt("o"), + optflag("save-temps"), optflag("noverify")); + auto binary = _vec.shift[str](args); + auto match; + alt (GetOpts.getopts(args, opts)) { + case (GetOpts.failure(?f)) { sess.err(GetOpts.fail_str(f)); fail; } + case (GetOpts.success(?m)) { match = m; } + } + if (!opt_present(match, "nowarn")) { + warn_wrong_compiler(); + } + if (opt_present(match, "h")) { + usage(sess, binary); + ret; + } + auto pretty = opt_present(match, "pretty"); + auto ls = opt_present(match, "ls"); + auto glue = opt_present(match, "glue"); + auto shared = opt_present(match, "shared"); + auto output_file = GetOpts.opt_maybe_str(match, "o"); + auto library_search_paths = GetOpts.opt_strs(match, "L"); + auto ot = trans.output_type_bitcode; + if (opt_present(match, "parse-only")) { + ot = trans.output_type_none; + } else if (opt_present(match, "S")) { + ot = trans.output_type_assembly; + } else if (opt_present(match, "c")) { + ot = trans.output_type_object; + } + auto verify = !opt_present(match, "noverify"); + auto save_temps = opt_present(match, "save-temps"); // FIXME: Maybe we should support -O0, -O1, -Os, etc - let bool optimize = false; + auto optimize = opt_present(match, "O"); + auto n_inputs = _vec.len[str](match.free); - auto i = 1u; - auto len = _vec.len[str](args); - - // FIXME: a getopt module would be nice. - while (i < len) { - auto arg = args.(i); - if (_str.byte_len(arg) > 0u && arg.(0) == '-' as u8) { - if (_str.eq(arg, "-nowarn")) { - do_warn = false; - } else if (_str.eq(arg, "-O")) { - optimize = true; - } else if (_str.eq(arg, "-glue")) { - glue = true; - } else if (_str.eq(arg, "-shared")) { - shared = true; - } else if (_str.eq(arg, "-pp")) { - pretty = true; - } else if (_str.eq(arg, "-ls")) { - ls = true; - } else if (_str.eq(arg, "-parse-only")) { - ot = trans.output_type_none; - } else if (_str.eq(arg, "-S")) { - ot = trans.output_type_assembly; - } else if (_str.eq(arg, "-c")) { - ot = trans.output_type_object; - } else if (_str.eq(arg, "-o")) { - if (i+1u < len) { - output_file = some(args.(i+1u)); - i += 1u; - } else { - usage(sess, args.(0)); - sess.err("-o requires an argument"); - } - } else if (_str.eq(arg, "-save-temps")) { - save_temps = true; - } else if (_str.eq(arg, "-L")) { - if (i+1u < len) { - library_search_paths += vec(args.(i+1u)); - i += 1u; - } else { - usage(sess, args.(0)); - sess.err("-L requires an argument"); - } - } else if (_str.eq(arg, "-noverify")) { - verify = false; - } else if (_str.eq(arg, "-h")) { - usage(sess, args.(0)); - } else { - usage(sess, args.(0)); - sess.err("unrecognized option: " + arg); - } - } else { - alt (input_file) { - case (some[str](_)) { - usage(sess, args.(0)); - sess.err("multiple inputs provided"); - } - case (none[str]) { - input_file = some[str](arg); - } - } + if (glue) { + if (n_inputs > 0u) { + sess.err("No input files allowed with --glue."); } - i += 1u; + auto out = option.from_maybe[str]("glue.bc", output_file); + middle.trans.make_common_glue(out, optimize, verify, save_temps, ot); + ret; } - if (do_warn) { - warn_wrong_compiler(); + if (n_inputs == 0u) { + sess.err("No input filename given."); + } else if (n_inputs > 1u) { + sess.err("Multiple input filenames provided."); } - if (glue) { + auto ifile = match.free.(0); + auto env = default_environment(sess, args.(0), ifile); + if (pretty) { + pretty_print_input(sess, env, ifile); + } else if (ls) { + front.creader.list_file_metadata(ifile, std.io.stdout()); + } else { alt (output_file) { case (none[str]) { - middle.trans.make_common_glue("glue.bc", optimize, verify, - save_temps, ot); - } - case (some[str](?s)) { - middle.trans.make_common_glue(s, optimize, verify, save_temps, - ot); + let vec[str] parts = _str.split(ifile, '.' as u8); + _vec.pop[str](parts); + parts += vec(".bc"); + auto ofile = _str.concat(parts); + compile_input(sess, env, ifile, ofile, shared, + optimize, verify, save_temps, ot, + library_search_paths); } - } - ret; - } - - alt (input_file) { - case (none[str]) { - usage(sess, args.(0)); - sess.err("no input filename"); - } - case (some[str](?ifile)) { - - auto env = default_environment(sess, args.(0), ifile); - if (pretty) { - pretty_print_input(sess, env, ifile); - } else if (ls) { - front.creader.list_file_metadata(ifile, std.io.stdout()); - } else { - alt (output_file) { - case (none[str]) { - let vec[str] parts = _str.split(ifile, '.' as u8); - _vec.pop[str](parts); - parts += vec(".bc"); - auto ofile = _str.concat(parts); - compile_input(sess, env, ifile, ofile, shared, - optimize, verify, save_temps, ot, - library_search_paths); - } - case (some[str](?ofile)) { - compile_input(sess, env, ifile, ofile, shared, - optimize, verify, save_temps, ot, - library_search_paths); - } - } + case (some[str](?ofile)) { + compile_input(sess, env, ifile, ofile, shared, + optimize, verify, save_temps, ot, + library_search_paths); } } } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 04bea450..24078767 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -630,7 +630,9 @@ fn ty_to_str(ctxt cx, &t typ) -> str { fn ty_to_abbrev_str(ctxt cx, t typ) -> str { auto f = def_to_str; auto ecx = @rec(ds=f, tcx=cx); - ret metadata.Encode.ty_str(ecx, typ); + auto s = metadata.Encode.ty_str(ecx, typ); + if (_str.byte_len(s) >= 64u) { s = _str.substr(s, 0u, 64u); } + ret s; } // Type folds diff --git a/src/lib/GetOpts.rs b/src/lib/GetOpts.rs new file mode 100644 index 00000000..f85ce85c --- /dev/null +++ b/src/lib/GetOpts.rs @@ -0,0 +1,249 @@ +/* Simple getopt alternative. Construct a vector of options, either by using + * reqopt, optopt, and optflag or by building them from components yourself, + * and pass them to getopts, along with a vector of actual arguments (not + * including argv[0]). You'll either get a failure code back, or a match. + * You'll have to verify whether the amount of 'free' arguments in the match + * is what you expect. Use opt_* accessors (bottom of the file) to get + * argument values out of the match object. + */ + +import option.some; +import option.none; + +tag name { long(str); short(char); } +tag hasarg { yes; no; maybe; } +tag occur { req; optional; multi; } + +type opt = rec(name name, hasarg hasarg, occur occur); + +fn mkname(str nm) -> name { + if (_str.char_len(nm) == 1u) { ret short(_str.char_at(nm, 0u)); } + else { ret long(nm); } +} +fn reqopt(str name) -> opt { + ret rec(name=mkname(name), hasarg=yes, occur=req); +} +fn optopt(str name) -> opt { + ret rec(name=mkname(name), hasarg=yes, occur=optional); +} +fn optflag(str name) -> opt { + ret rec(name=mkname(name), hasarg=no, occur=optional); +} +fn optmulti(str name) -> opt { + ret rec(name=mkname(name), hasarg=yes, occur=multi); +} + +tag optval { + val(str); + given; +} + +type match = rec(vec[opt] opts, vec[mutable vec[optval]] vals, vec[str] free); + +fn is_arg(str arg) -> bool { + ret _str.byte_len(arg) > 1u && arg.(0) == '-' as u8; +} +fn name_str(name nm) -> str { + alt (nm) { + case (short(?ch)) {ret _str.from_char(ch);} + case (long(?s)) {ret s;} + } +} + +// FIXME rustboot workaround +fn name_eq(name a, name b) -> bool { + alt (a) { + case (long(?a)) { + alt (b) { + case (long(?b)) { ret _str.eq(a, b); } + case (_) { ret false; } + } + } + case (_) { if (a == b) { ret true; } else {ret false; } } + } +} +fn find_opt(vec[opt] opts, name nm) -> option.t[uint] { + auto i = 0u; + auto l = _vec.len[opt](opts); + while (i < l) { + if (name_eq(opts.(i).name, nm)) { ret some[uint](i); } + i += 1u; + } + ret none[uint]; +} + +tag fail_ { + argument_missing(str); + unrecognized_option(str); + option_missing(str); + option_duplicated(str); +} + +fn fail_str(fail_ f) -> str { + alt (f) { + case (argument_missing(?nm)) { + ret "Argument to option '" + nm + "' missing."; + } + case (unrecognized_option(?nm)) { + ret "Unrecognized option: '" + nm + "'."; + } + case (option_missing(?nm)) { + ret "Required option '" + nm + "' missing."; + } + case (option_duplicated(?nm)) { + ret "Option '" + nm + "' given more than once."; + } + } +} + +tag result { + success(match); + failure(fail_); +} + +fn getopts(vec[str] args, vec[opt] opts) -> result { + auto n_opts = _vec.len[opt](opts); + fn empty_(uint x) -> vec[optval]{ret _vec.empty[optval]();} + auto f = empty_; + auto vals = _vec.init_fn_mut[vec[optval]](f, n_opts); + let vec[str] free = vec(); + + auto l = _vec.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); + } else if (_str.eq(cur, "--")) { + free += _vec.slice[str](args, i + 1u, l); + break; + } else { + auto names; + auto i_arg = option.none[str]; + if (cur.(1) == '-' as u8) { + auto tail = _str.slice(cur, 2u, curlen); + auto eq = _str.index(tail, '=' as u8); + if (eq == -1) { + names = vec(long(tail)); + } else { + names = vec(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 = vec(); + while (j < curlen) { + auto range = _str.char_range_at(cur, j); + _vec.push[name](names, short(range._0)); + j = range._1; + } + } + auto name_pos = 0u; + for (name nm in names) { + name_pos += 1u; + auto optid; + alt (find_opt(opts, nm)) { + case (some[uint](?id)) {optid = id;} + case (none[uint]) { + ret failure(unrecognized_option(name_str(nm))); + } + } + alt (opts.(optid).hasarg) { + case (no) { + _vec.push[optval](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) || + i + 1u == l || is_arg(args.(i + 1u))) { + _vec.push[optval](vals.(optid), given); + } else { + i += 1u; + _vec.push[optval](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))); + } else if (i + 1u == l) { + ret failure(argument_missing(name_str(nm))); + } else { + i += 1u; + _vec.push[optval](vals.(optid), val(args.(i))); + } + } + } + } + } + i += 1u; + } + + i = 0u; + while (i < n_opts) { + auto n = _vec.len[optval](vals.(i)); + auto occ = opts.(i).occur; + if (occ == req) {if (n == 0u) { + ret failure(option_missing(name_str(opts.(i).name))); + }} + if (occ != multi) {if (n > 1u) { + ret failure(option_duplicated(name_str(opts.(i).name))); + }} + i += 1u; + } + + ret success(rec(opts=opts, vals=vals, free=free)); +} + +fn opt_vals(match m, str nm) -> vec[optval] { + alt (find_opt(m.opts, mkname(nm))) { + case (some[uint](?id)) { ret m.vals.(id); } + case (none[uint]) { + log_err "No option '" + nm + "' defined."; + fail; + } + } +} +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; +} +fn opt_str(match m, str nm) -> str { + alt (opt_val(m, nm)) { + case (val(?s)) { ret s; } + case (_) { fail; } + } +} +fn opt_strs(match m, str nm) -> vec[str] { + let vec[str] acc = vec(); + for (optval v in opt_vals(m, nm)) { + alt (v) { + case (val(?s)) { _vec.push[str](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]; } + alt (vals.(0)) { + case (val(?s)) { ret some[str](s); } + case (_) { ret none[str]; } + } +} + +// Local Variables: +// mode: rust; +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/lib/Term.rs b/src/lib/Term.rs new file mode 100644 index 00000000..9bf90b1c --- /dev/null +++ b/src/lib/Term.rs @@ -0,0 +1,54 @@ +// Simple ANSI color library. +// +// TODO: Windows support. + +const u8 color_black = 0u8; +const u8 color_red = 1u8; +const u8 color_green = 2u8; +const u8 color_yellow = 3u8; +const u8 color_blue = 4u8; +const u8 color_magenta = 5u8; +const u8 color_cyan = 6u8; +const u8 color_light_gray = 7u8; +const u8 color_light_grey = 7u8; +const u8 color_dark_gray = 8u8; +const u8 color_dark_grey = 8u8; +const u8 color_bright_red = 9u8; +const u8 color_bright_green = 10u8; +const u8 color_bright_yellow = 11u8; +const u8 color_bright_blue = 12u8; +const u8 color_bright_magenta = 13u8; +const u8 color_bright_cyan = 14u8; +const u8 color_bright_white = 15u8; + +fn esc(io.buf_writer writer) { + writer.write(vec(0x1bu8, '[' as u8)); +} + +fn reset(io.buf_writer writer) { + esc(writer); + writer.write(vec('0' as u8, 'm' as u8)); +} + +fn set_color(io.buf_writer writer, u8 first_char, u8 color) { + check (color < 16u8); + + esc(writer); + if (color >= 8u8) { + writer.write(vec('1' as u8, ';' as u8)); + color -= 8u8; + } + writer.write(vec(first_char, ('0' as u8) + color, 'm' as u8)); +} + +fn fg(io.buf_writer writer, u8 color) { + ret set_color(writer, '3' as u8, color); +} + +fn bg(io.buf_writer writer, u8 color) { + ret set_color(writer, '4' as u8, color); +} + +// export fg; +// export bg; + diff --git a/src/lib/_str.rs b/src/lib/_str.rs index 3922acb6..41a86cf3 100644 --- a/src/lib/_str.rs +++ b/src/lib/_str.rs @@ -391,10 +391,14 @@ fn ends_with(str haystack, str needle) -> bool { } fn substr(str s, uint begin, uint len) -> str { + ret slice(s, begin, begin + len); +} + +fn slice(str s, uint begin, uint end) -> str { let str accum = ""; let uint i = begin; - while (i < begin+len) { - accum += unsafe_from_byte(s.(i)); + while (i < end) { + push_byte(accum, s.(i)); i += 1u; } ret accum; diff --git a/src/lib/std.rc b/src/lib/std.rc index 1056f375..8a9ee42d 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -70,6 +70,8 @@ mod ebml; mod UFind; mod ExtFmt; mod Box; +mod GetOpts; +mod Term; // Local Variables: // mode: rust; |