diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 3547b45dfa71f..55e91f0952438 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -218,6 +218,8 @@ pub struct RenderOptions { pub extern_html_root_urls: BTreeMap, /// If present, suffix added to CSS/JavaScript files when referencing them in generated pages. pub resource_suffix: String, + /// Links displayed on the crate root page. + pub crate_root_links: BTreeMap, /// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by /// default. // @@ -270,6 +272,36 @@ impl Options { /// Parses the given command-line for options. If an error message or other early-return has /// been printed, returns `Err` with the exit code. pub fn from_matches(matches: &getopts::Matches) -> Result { + fn parse_keyval_opt_internal( + matches: &getopts::Matches, + opt_name: &'static str, + empty_err: &'static str, + invalid_form_err: &'static str, + ) -> Result, &'static str> { + let mut externs = BTreeMap::new(); + for arg in &(matches).opt_strs(opt_name) { + let mut parts = arg.splitn(2, '='); + let name = parts.next().ok_or(empty_err)?; + let url = parts.next().ok_or(invalid_form_err)?; + externs.insert(name.to_string(), url.to_string()); + } + + Ok(externs) + } + /// Extracts key-value arguments (such as for `--extern-html-root-url`) from `matches` and returns + /// a map of crate names to the given URLs. If an argument was ill-formed, returns an error + /// describing the issue. + macro_rules! parse_keyval_opt { + ($matches:expr, $opt_name:literal) => { + parse_keyval_opt_internal( + $matches, + $opt_name, + concat!("--", $opt_name, "must not be empty"), + concat!("--", $opt_name, "must be of the form name=url"), + ) + }; + } + // Check for unstable options. nightly_options::check_nightly_options(&matches, &opts()); @@ -366,7 +398,15 @@ impl Options { .map(|s| SearchPath::from_cli_opt(s, error_format)) .collect(); let externs = parse_externs(&matches, &debugging_options, error_format); - let extern_html_root_urls = match parse_extern_html_roots(&matches) { + let extern_html_root_urls = match parse_keyval_opt!(&matches, "extern-html-root-url") { + Ok(ex) => ex, + Err(err) => { + diag.struct_err(err).emit(); + return Err(1); + } + }; + + let crate_root_links = match parse_keyval_opt!(&matches, "crate-root-link") { Ok(ex) => ex, Err(err) => { diag.struct_err(err).emit(); @@ -609,6 +649,7 @@ impl Options { generate_search_filter, document_private, document_hidden, + crate_root_links, }, output_format, }) @@ -654,20 +695,3 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han } } } - -/// Extracts `--extern-html-root-url` arguments from `matches` and returns a map of crate names to -/// the given URLs. If an `--extern-html-root-url` argument was ill-formed, returns an error -/// describing the issue. -fn parse_extern_html_roots( - matches: &getopts::Matches, -) -> Result, &'static str> { - let mut externs = BTreeMap::new(); - for arg in &matches.opt_strs("extern-html-root-url") { - let mut parts = arg.splitn(2, '='); - let name = parts.next().ok_or("--extern-html-root-url must not be empty")?; - let url = parts.next().ok_or("--extern-html-root-url must be of the form name=url")?; - externs.insert(name.to_string(), url.to_string()); - } - - Ok(externs) -} diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 5fb2d9f6f917c..3c403a3f17d0d 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -157,6 +157,8 @@ crate struct SharedContext { pub edition: Edition, pub codes: ErrorCodes, playground: Option, + /// Links displayed on the crate root page. + pub crate_root_links: BTreeMap, } impl Context { @@ -396,6 +398,7 @@ impl FormatRenderer for Context { resource_suffix, static_root_path, generate_search_filter, + crate_root_links, .. } = options; @@ -466,6 +469,7 @@ impl FormatRenderer for Context { edition, codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()), playground, + crate_root_links, }; // Add the default themes to the `Vec` of stylepaths @@ -3895,6 +3899,27 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca } write!(buffer, "
"); + + if it.is_crate() && !cx.shared.crate_root_links.is_empty() { + let mut links_html = String::new(); + for (name, url) in &cx.shared.crate_root_links { + links_html.push_str(&format!( + "
  • {}
  • ", + Escape(url), + Escape(name), + )); + } + write!( + buffer, + "
    \ +
      \ + {}\ +
    \ +
    ", + links_html + ); + }; + if it.is_crate() { write!( buffer, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 65bc089faf428..b7bcc65fd9751 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -406,6 +406,9 @@ fn opts() -> Vec { "specified the rustc-like binary to use as the test builder", ) }), + unstable("crate-root-link", |o| { + o.optmulti("", "crate-root-link", "", "Specifies links to display on the crate root") + }), ] } diff --git a/src/stdarch b/src/stdarch new file mode 160000 index 0000000000000..45340c0e2fdad --- /dev/null +++ b/src/stdarch @@ -0,0 +1 @@ +Subproject commit 45340c0e2fdadf2f131ef43cb683b5cafab0ff15 diff --git a/x.py b/x.py index 7973730ef177c..6186ebb5d48a5 100755 --- a/x.py +++ b/x.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # This file is only a "symlink" to bootstrap.py, all logic should go there.