diff --git a/Makefile.in b/Makefile.in index cf6fcd42021..30aefd02cd2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -134,6 +134,7 @@ CFG_LIBFUZZER :=$(call CFG_LIB_NAME,fuzzer) CFG_LIBRUSTPKG :=$(call CFG_LIB_NAME,rustpkg) CFG_LIBRUSTDOC :=$(call CFG_LIB_NAME,rustdoc) CFG_LIBRUSTI :=$(call CFG_LIB_NAME,rusti) +CFG_LIBRUST :=$(call CFG_LIB_NAME,rust) STDLIB_GLOB :=$(call CFG_LIB_GLOB,std) CORELIB_GLOB :=$(call CFG_LIB_GLOB,core) @@ -143,6 +144,7 @@ LIBFUZZER_GLOB :=$(call CFG_LIB_GLOB,fuzzer) LIBRUSTPKG_GLOB :=$(call CFG_LIB_GLOB,rustpkg) LIBRUSTDOC_GLOB :=$(call CFG_LIB_GLOB,rustdoc) LIBRUSTI_GLOB :=$(call CFG_LIB_GLOB,rusti) +LIBRUST_GLOB :=$(call CFG_LIB_GLOB,rust) STDLIB_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,std) CORELIB_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,core) LIBRUSTC_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustc) @@ -151,6 +153,7 @@ LIBFUZZER_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,fuzzer) LIBRUSTPKG_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustpkg) LIBRUSTDOC_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rustdoc) LIBRUSTI_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rusti) +LIBRUST_DSYM_GLOB :=$(call CFG_LIB_DSYM_GLOB,rust) # version-string calculation CFG_GIT_DIR := $(CFG_SRC_DIR).git @@ -374,10 +377,12 @@ CSREQ$(1)_T_$(2)_H_$(3) = \ $$(HBIN$(1)_H_$(3))/rustpkg$$(X) \ $$(HBIN$(1)_H_$(3))/rustdoc$$(X) \ $$(HBIN$(1)_H_$(3))/rusti$$(X) \ + $$(HBIN$(1)_H_$(3))/rust$$(X) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBFUZZER) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTPKG) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTDOC) \ $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUSTI) \ + $$(HLIB$(1)_H_$(3))/$$(CFG_LIBRUST) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_CORELIB) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBSYNTAX) \ @@ -385,7 +390,8 @@ CSREQ$(1)_T_$(2)_H_$(3) = \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBFUZZER) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTPKG) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTDOC) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTI) + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTI) \ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUST) ifeq ($(1),0) # Don't run the the stage0 compiler under valgrind - that ship has sailed diff --git a/mk/clean.mk b/mk/clean.mk index 3b35071c818..f02e2427a0c 100644 --- a/mk/clean.mk +++ b/mk/clean.mk @@ -68,6 +68,7 @@ clean$(1)_H_$(2): $(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X) $(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X) + $(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBFUZZER) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC) @@ -77,6 +78,7 @@ clean$(1)_H_$(2): $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTC) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBSYNTAX) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTI) + $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUST) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CORELIB_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB) @@ -85,6 +87,7 @@ clean$(1)_H_$(2): $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB) + $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUST_GLOB) $(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM) $(Q)rm -f $$(HLIB$(1)_H_$(2))/libstd.rlib diff --git a/mk/dist.mk b/mk/dist.mk index 5b6740461e6..3684b9c4544 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -27,6 +27,7 @@ PKG_FILES := \ driver \ librustpkg \ librusti \ + librust \ librustc \ compiletest \ etc \ diff --git a/mk/install.mk b/mk/install.mk index 7f3ec816e02..ebbe5f007f1 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -60,6 +60,8 @@ install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTDOC_GLOB)) $$(Q)$$(call INSTALL_LIB, \ $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTI_GLOB)) + $$(Q)$$(call INSTALL_LIB, \ + $$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUST_GLOB)) $$(Q)$$(call INSTALL,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a) endef @@ -90,15 +92,18 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_HOST_TRIPLE)_H_$(CFG_HOST_TRIPLE)) $(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X)) $(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X)) $(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X)) + $(Q)$(call INSTALL,$(HB2),$(PHB),rust$(X)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTC)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTPKG)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTDOC)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUSTI)) + $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_LIBRUST)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(CORELIB_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(STDLIB_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTC_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBSYNTAX_GLOB)) $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTI_GLOB)) + $(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUST_GLOB)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUNTIME)) $(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUSTLLVM)) $(Q)$(call INSTALL,$(S)/man, \ @@ -114,12 +119,14 @@ uninstall: $(Q)rm -f $(PHB)/rustc$(X) $(Q)rm -f $(PHB)/rustpkg$(X) $(Q)rm -f $(PHB)/rusti$(X) + $(Q)rm -f $(PHB)/rust$(X) $(Q)rm -f $(PHB)/rustdoc$(X) $(Q)rm -f $(PHL)/$(CFG_RUSTLLVM) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTPKG) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTC) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTDOC) $(Q)rm -f $(PHL)/$(CFG_LIBRUSTI) + $(Q)rm -f $(PHL)/$(CFG_LIBRUST) $(Q)rm -f $(PHL)/$(CFG_RUNTIME) $(Q)for i in \ $(call HOST_LIB_FROM_HL_GLOB,$(CORELIB_GLOB)) \ @@ -129,6 +136,7 @@ uninstall: $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOC_GLOB)) \ $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTI_GLOB)) \ + $(call HOST_LIB_FROM_HL_GLOB,$(LIBRUST_GLOB)) \ ; \ do rm -f $$i ; \ done diff --git a/mk/pp.mk b/mk/pp.mk index 772365b1058..653cabfce5f 100644 --- a/mk/pp.mk +++ b/mk/pp.mk @@ -19,7 +19,8 @@ else $(S)src/test/*/*/*.rs) \ $(wildcard $(S)src/fuzzer/*.rs) \ $(wildcard $(S)src/rustpkg/*.rs) \ - $(wildcard $(S)src/rusti/*.rs) + $(wildcard $(S)src/rusti/*.rs) \ + $(wildcard $(S)src/rust/*.rs) PP_INPUTS_FILTERED = $(shell echo $(PP_INPUTS) | xargs grep -L \ "no-reformat\|xfail-pretty\|xfail-test") diff --git a/mk/tests.mk b/mk/tests.mk index 8bcf5d5ad10..116f6ffe568 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -14,7 +14,7 @@ ###################################################################### # The names of crates that must be tested -TEST_CRATES = core std syntax rustc rustdoc rusti rustpkg +TEST_CRATES = core std syntax rustc rustdoc rusti rust rustpkg # Markdown files under doc/ that should have their code extracted and run DOC_TEST_NAMES = tutorial tutorial-ffi tutorial-macros tutorial-borrowed-ptr tutorial-tasks rust @@ -241,6 +241,12 @@ $(3)/test/rustitest.stage$(1)-$(2)$$(X): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test +$(3)/test/rusttest.stage$(1)-$(2)$$(X): \ + $$(RUST_LIB) $$(RUST_INPUTS) \ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test + $(3)/test/rustdoctest.stage$(1)-$(2)$$(X): \ $$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC) @@ -464,20 +470,20 @@ $(foreach host,$(CFG_TARGET_TRIPLES), \ define DEF_RUN_DOC_TEST -DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \ +DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4) := \ $$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \ --src-base $(3)/test/doc-$(4)/ \ --build-base $(3)/test/doc-$(4)/ \ --mode run-pass -check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)) +check-stage$(1)-T-$(2)-H-$(3)-doc-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)) -$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ +$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): \ $$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \ doc-$(4)-extract$(3) @$$(call E, run doc-$(4): $$<) $$(Q)$$(call CFG_RUN_CTEST,$(1),$$<,$(3)) \ - $$(DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \ + $$(DOC_TEST_ARGS$(1)-T-$(2)-H-$(3)-doc-$(4)) \ --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),doc-$(4)) \ && touch $$@ diff --git a/mk/tools.mk b/mk/tools.mk index 1554d760a49..22f109be47f 100644 --- a/mk/tools.mk +++ b/mk/tools.mk @@ -30,6 +30,10 @@ RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs) RUSTI_LIB := $(S)src/librusti/rusti.rc RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs) +# Rust, the convenience tool +RUST_LIB := $(S)src/librust/rust.rc +RUST_INPUTS := $(wildcard $(S)src/librust/*.rs) + # FIXME: These are only built for the host arch. Eventually we'll # have tools that need to built for other targets. define TOOLS_STAGE_N_TARGET @@ -102,6 +106,21 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X): \ @$$(call E, compile_and_link: $$@) $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rusti -o $$@ $$< +$$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUST): \ + $$(RUST_LIB) $$(RUST_INPUTS) \ + $$(TSREQ$(1)_T_$(4)_H_$(3)) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_CORELIB) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_STDLIB) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUSTC) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@ + +$$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X): \ + $$(DRIVER_CRATE) \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUST) + @$$(call E, compile_and_link: $$@) + $$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rust -o $$@ $$< + endef define TOOLS_STAGE_N_HOST @@ -185,6 +204,23 @@ $$(HBIN$(2)_H_$(4))/rusti$$(X): \ @$$(call E, cp: $$@) $$(Q)cp $$< $$@ +$$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUST): \ + $$(TLIB$(1)_T_$(4)_H_$(3))/$$(CFG_LIBRUST) \ + $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUSTC) \ + $$(HSREQ$(2)_H_$(4)) + @$$(call E, cp: $$@) + $$(Q)cp $$< $$@ + $$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUST_GLOB) \ + $$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUST_DSYM_GLOB)) \ + $$(HLIB$(2)_H_$(4)) + +$$(HBIN$(2)_H_$(4))/rust$$(X): \ + $$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X) \ + $$(HLIB$(2)_H_$(4))/$$(CFG_LIBRUST) \ + $$(HSREQ$(2)_H_$(4)) + @$$(call E, cp: $$@) + $$(Q)cp $$< $$@ + endef $(foreach host,$(CFG_TARGET_TRIPLES), \ diff --git a/src/driver/driver.rs b/src/driver/driver.rs index b2c4f69d302..2fc50eb6e75 100644 --- a/src/driver/driver.rs +++ b/src/driver/driver.rs @@ -23,6 +23,9 @@ extern mod this(name = "rustdoc", vers = "0.6"); #[cfg(rusti)] extern mod this(name = "rusti", vers = "0.6"); +#[cfg(rust)] +extern mod this(name = "rust", vers = "0.6"); + #[cfg(rustc)] extern mod this(name = "rustc", vers = "0.6"); diff --git a/src/librust/rust.rc b/src/librust/rust.rc new file mode 100644 index 00000000000..950623b8760 --- /dev/null +++ b/src/librust/rust.rc @@ -0,0 +1,235 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// rust - central access to other rust tools +// XXX: Make commands run and test emit proper file endings on winds +// XXX: Make run only accept source that emits an executable + +#[link(name = "rust", + vers = "0.6", + uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c", + url = "https://github.com/mozilla/rust/tree/master/src/rust")]; + +#[crate_type = "lib"]; + +extern mod core(vers = "0.6"); + +use core::run; + +enum ValidUsage { + Valid, Invalid +} + +impl ValidUsage { + fn is_valid(&self) -> bool { match *self { + Valid => true, + Invalid => false + }} +} + +enum Action { + Exec(&str), + Call(&fn(args: &[~str]) -> ValidUsage) +} + +enum UsageSource { + UsgExec(&str), + UsgStr(&str) +} + +struct Command { + cmd: &str, + action: Action, + usage_line: &str, + usage_full: UsageSource +} + +const commands: &[Command] = &[ + Command{ + cmd: "build", + action: Exec("rustc"), + usage_line: "compile rust source files", + usage_full: UsgExec("rustc --help") + }, + Command{ + cmd: "run", + action: Call(cmd_run), + usage_line: "build a executable, and run it", + usage_full: UsgStr( + "The run command is an shortcut for the command line \n\ + \"rustc -o ~ && ./~\".\ + \n\nUsage:\trust run " + ) + }, + Command{ + cmd: "test", + action: Call(cmd_test), + usage_line: "build a test executable, and run it", + usage_full: UsgStr( + "The test command is an shortcut for the command line \n\ + \"rustc --test -o test~ && \ + ./test~\"\n\nUsage:\trust test " + ) + }, + Command{ + cmd: "doc", + action: Exec("rustdoc"), + usage_line: "generate documentation from doc comments", + usage_full: UsgExec("rustdoc --help") + }, + Command{ + cmd: "pkg", + action: Exec("rustpkg"), + usage_line: "download, build, install rust packages", + usage_full: UsgExec("rustpkg --help") + }, + Command{ + cmd: "sketch", + action: Exec("rusti"), + usage_line: "run a rust interpreter", + usage_full: UsgStr("\nUsage:\trusti") + }, + Command{ + cmd: "help", + action: Call(cmd_help), + usage_line: "show detailed usage of a command", + usage_full: UsgStr( + "The help command displays the usage text of another command.\n\ + The text is either build in, or provided by the corresponding \ + program.\n\nUsage:\trust help " + ) + } +]; + +fn find_cmd(command_string: &str) -> Option { + do commands.find |command| { + command.cmd == command_string + } +} + +fn cmd_help(args: &[~str]) -> ValidUsage { + fn print_usage(command_string: ~str) -> ValidUsage { + match find_cmd(command_string) { + Some(command) => { + match command.action { + Exec(s) => io::println(fmt!( + "The %s command is an alias for the %s program.", + command.cmd, s)), + _ => () + } + match command.usage_full { + UsgStr(msg) => io::println(fmt!("%s\n", msg)), + UsgExec(commandline) => { + let words = str::words(commandline); + let (prog, args) = (words.head(), words.tail()); + run::run_program(prog, args); + } + } + Valid + }, + None => Invalid + } + } + + match args { + [command_string] => print_usage(command_string), + _ => Invalid + } +} + +fn cmd_test(args: &[~str]) -> ValidUsage { + match args { + [filename] => { + let test_exec = Path(filename).filestem().unwrap() + "test~"; + if run::run_program("rustc", [ + ~"--test", + filename.to_owned(), + ~"-o", + test_exec.to_owned() + ]) == 0 { + run::run_program(~"./" + test_exec, []); + } + Valid + } + _ => Invalid + } +} + +fn cmd_run(args: &[~str]) -> ValidUsage { + match args { + [filename] => { + let exec = Path(filename).filestem().unwrap() + "~"; + if run::run_program("rustc", [ + filename.to_owned(), + ~"-o", + exec.to_owned() + ]) == 0 { + run::run_program(~"./"+exec, []); + } + Valid + } + _ => Invalid + } +} + +fn do_command(command: &Command, args: &[~str]) -> ValidUsage { + match command.action { + Call(f) => f(args), + Exec(commandline) => { + let words = str::words(commandline); + let (prog, prog_args) = (words.head(), words.tail()); + let exitstatus = run::run_program(prog, prog_args + args); + os::set_exit_status(exitstatus); + Valid + } + } +} + +fn usage() { + const indent: uint = 8; + + io::print( + "The rust tool is a convenience for managing rust source code.\n\ + It acts as a shortcut for programs of the rust tool chain.\n\ + \n\ + Usage:\trust [arguments]\n\ + \n\ + The commands are:\n\ + \n" + ); + + for commands.each |command| { + let padding = str::repeat(" ", indent - command.cmd.len()); + io::println(fmt!(" %s%s%s", + command.cmd, padding, command.usage_line)); + } + + io::print( + "\n\ + Use \"rust help \" for more information about a command.\n\ + \n" + ); + +} + +fn main() { + let args = os::args().tail(); + + if !args.is_empty() { + for commands.each |command| { + if command.cmd == args.head() { + let result = do_command(command, args.tail()); + if result.is_valid() { return; } + } + } + } + + usage(); +}