X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=src%2Flibrustdoc%2Fhtml%2Fsources.rs;h=e639fadeb96733ddb5848e6ef9c677614eaaa5b0;hb=7c4a9a971ca6962533bed01ffbd0c1f6b5250abc;hp=54e296959b0ec97fb569a2210d1e0054cece775f;hpb=e5a01b97ee9a3dc45d7f5055c8b0f4482b2ebad7;p=rust.git diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 54e296959b0..2c90bf4fadc 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -4,7 +4,7 @@ use crate::html::format::Buffer; use crate::html::highlight; use crate::html::layout; -use crate::html::render::{Context, BASIC_KEYWORDS}; +use crate::html::render::Context; use crate::visit::DocVisitor; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -13,6 +13,7 @@ use rustc_session::Session; use rustc_span::source_map::FileName; +use std::cell::RefCell; use std::ffi::OsStr; use std::fs; use std::path::{Component, Path, PathBuf}; @@ -72,12 +73,22 @@ fn add_local_source(&mut self, item: &clean::Item) { return; } - let mut href = String::new(); - clean_path(self.src_root, &p, false, |component| { - href.push_str(&component.to_string_lossy()); - href.push('/'); - }); + let href = RefCell::new(PathBuf::new()); + clean_path( + &self.src_root, + &p, + |component| { + href.borrow_mut().push(component); + }, + || { + href.borrow_mut().pop(); + }, + ); + let mut href = href.into_inner().to_string_lossy().to_string(); + if let Some(c) = href.as_bytes().last() && *c != b'/' { + href.push('/'); + } let mut src_fname = p.file_name().expect("source has no filename").to_os_string(); src_fname.push(".html"); href.push_str(&src_fname.to_string_lossy()); @@ -180,13 +191,28 @@ fn emit_source( let shared = Rc::clone(&self.cx.shared); // Create the intermediate directories - let mut cur = self.dst.clone(); - let mut root_path = String::from("../../"); - clean_path(&shared.src_root, &p, false, |component| { - cur.push(component); - root_path.push_str("../"); - }); + let cur = RefCell::new(PathBuf::new()); + let root_path = RefCell::new(PathBuf::new()); + + clean_path( + &shared.src_root, + &p, + |component| { + cur.borrow_mut().push(component); + root_path.borrow_mut().push(".."); + }, + || { + cur.borrow_mut().pop(); + root_path.borrow_mut().pop(); + }, + ); + let root_path = PathBuf::from("../../").join(root_path.into_inner()); + let mut root_path = root_path.to_string_lossy(); + if let Some(c) = root_path.as_bytes().last() && *c != b'/' { + root_path += "/"; + } + let mut cur = self.dst.join(cur.into_inner()); shared.ensure_dir(&cur)?; let src_fname = p.file_name().expect("source has no filename").to_os_string(); @@ -202,7 +228,6 @@ fn emit_source( root_path: &root_path, static_root_path: shared.static_root_path.as_deref(), description: &desc, - keywords: BASIC_KEYWORDS, resource_suffix: &shared.resource_suffix, }; let v = layout::render( @@ -232,11 +257,13 @@ fn emit_source( /// Takes a path to a source file and cleans the path to it. This canonicalizes /// things like ".." to components which preserve the "top down" hierarchy of a /// static HTML tree. Each component in the cleaned path will be passed as an -/// argument to `f`. The very last component of the path (ie the file name) will -/// be passed to `f` if `keep_filename` is true, and ignored otherwise. -pub(crate) fn clean_path(src_root: &Path, p: &Path, keep_filename: bool, mut f: F) +/// argument to `f`. The very last component of the path (ie the file name) is ignored. +/// If a `..` is encountered, the `parent` closure will be called to allow the callee to +/// handle it. +pub(crate) fn clean_path(src_root: &Path, p: &Path, mut f: F, mut parent: P) where F: FnMut(&OsStr), + P: FnMut(), { // make it relative, if possible let p = p.strip_prefix(src_root).unwrap_or(p); @@ -244,12 +271,12 @@ pub(crate) fn clean_path(src_root: &Path, p: &Path, keep_filename: bool, mut let mut iter = p.components().peekable(); while let Some(c) = iter.next() { - if !keep_filename && iter.peek().is_none() { + if iter.peek().is_none() { break; } match c { - Component::ParentDir => f("up".as_ref()), + Component::ParentDir => parent(), Component::Normal(c) => f(c), _ => continue, } @@ -276,7 +303,7 @@ pub(crate) fn print_src( let mut line_numbers = Buffer::empty_from(buf); let extra; line_numbers.write_str("
");
-    let current_href = &context
+    let current_href = context
         .href_from_span(clean::Span::new(file_span), false)
         .expect("only local crates should have sources emitted");
     match source_context {