aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGraydon Hoare <[email protected]>2011-04-26 20:39:33 +0000
committerGraydon Hoare <[email protected]>2011-04-26 20:39:33 +0000
commitbc6e9815379e31ac42b4d9fd2b0e20f708c1cc1c (patch)
treef9ccd0dac288b2751536a6e552ec8e094e2a6739 /src
parentVarious bits of trans lint, nothing major. (diff)
parentrustc: Cap ridiculous type name sizes (diff)
downloadrust-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.rs202
-rw-r--r--src/comp/middle/ty.rs4
-rw-r--r--src/lib/GetOpts.rs249
-rw-r--r--src/lib/Term.rs54
-rw-r--r--src/lib/_str.rs8
-rw-r--r--src/lib/std.rc2
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;