auto merge of #13440 : huonw/rust/strbuf, r=alexcrichton
libstd: Implement `StrBuf`, a new string buffer type like `Vec`, and port all code over to use it. Rebased & tests-fixed version of https://github.com/mozilla/rust/pull/13269
This commit is contained in:
commit
cea8def620
66 changed files with 1070 additions and 983 deletions
|
|
@ -24,12 +24,13 @@ use rustc::metadata::cstore;
|
|||
use rustc::metadata::csearch;
|
||||
use rustc::metadata::decoder;
|
||||
|
||||
use std::local_data;
|
||||
use std::strbuf::StrBuf;
|
||||
use std;
|
||||
|
||||
use core;
|
||||
use doctree;
|
||||
use visit_ast;
|
||||
use std::local_data;
|
||||
|
||||
pub trait Clean<T> {
|
||||
fn clean(&self) -> T;
|
||||
|
|
@ -917,7 +918,7 @@ impl Clean<PathSegment> for ast::PathSegment {
|
|||
fn path_to_str(p: &ast::Path) -> ~str {
|
||||
use syntax::parse::token;
|
||||
|
||||
let mut s = ~"";
|
||||
let mut s = StrBuf::new();
|
||||
let mut first = true;
|
||||
for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) {
|
||||
if !first || p.global {
|
||||
|
|
@ -927,7 +928,7 @@ fn path_to_str(p: &ast::Path) -> ~str {
|
|||
}
|
||||
s.push_str(i.get());
|
||||
}
|
||||
s
|
||||
s.into_owned()
|
||||
}
|
||||
|
||||
impl Clean<~str> for ast::Ident {
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@
|
|||
//! them in the future to instead emit any format desired.
|
||||
|
||||
use std::fmt;
|
||||
use std::local_data;
|
||||
use std::io;
|
||||
use std::local_data;
|
||||
use std::strbuf::StrBuf;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
|
|
@ -185,7 +186,7 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
-> fmt::Result
|
||||
{
|
||||
// The generics will get written to both the title and link
|
||||
let mut generics = ~"";
|
||||
let mut generics = StrBuf::new();
|
||||
let last = path.segments.last().unwrap();
|
||||
if last.lifetimes.len() > 0 || last.types.len() > 0 {
|
||||
let mut counter = 0;
|
||||
|
|
@ -219,7 +220,7 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
let amt = path.segments.len() - 1;
|
||||
match rel_root {
|
||||
Some(root) => {
|
||||
let mut root = root;
|
||||
let mut root = StrBuf::from_str(root);
|
||||
for seg in path.segments.slice_to(amt).iter() {
|
||||
if "super" == seg.name || "self" == seg.name {
|
||||
try!(write!(w, "{}::", seg.name));
|
||||
|
|
@ -228,7 +229,7 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
root.push_str("/");
|
||||
try!(write!(w, "<a class='mod'
|
||||
href='{}index.html'>{}</a>::",
|
||||
root,
|
||||
root.as_slice(),
|
||||
seg.name));
|
||||
}
|
||||
}
|
||||
|
|
@ -244,7 +245,7 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
match info(&**cache) {
|
||||
// This is a documented path, link to it!
|
||||
Some((ref fqp, shortty)) if abs_root.is_some() => {
|
||||
let mut url = abs_root.unwrap();
|
||||
let mut url = StrBuf::from_str(abs_root.unwrap());
|
||||
let to_link = fqp.slice_to(fqp.len() - 1);
|
||||
for component in to_link.iter() {
|
||||
url.push_str(*component);
|
||||
|
|
@ -271,7 +272,7 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
|
|||
try!(write!(w, "{}", last.name));
|
||||
}
|
||||
}
|
||||
try!(write!(w, "{}", generics));
|
||||
try!(write!(w, "{}", generics.as_slice()));
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
|
|
@ -430,7 +431,7 @@ impl fmt::Show for clean::FnDecl {
|
|||
impl<'a> fmt::Show for Method<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let Method(selfty, d) = *self;
|
||||
let mut args = ~"";
|
||||
let mut args = StrBuf::new();
|
||||
match *selfty {
|
||||
clean::SelfStatic => {},
|
||||
clean::SelfValue => args.push_str("self"),
|
||||
|
|
@ -455,7 +456,8 @@ impl<'a> fmt::Show for Method<'a> {
|
|||
}
|
||||
args.push_str(format!("{}", input.type_));
|
||||
}
|
||||
write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
write!(f.buf,
|
||||
"({args}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
args = args,
|
||||
arrow = match d.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = d.output)
|
||||
|
|
|
|||
|
|
@ -33,13 +33,14 @@
|
|||
//! These tasks are not parallelized (they haven't been a bottleneck yet), and
|
||||
//! both occur before the crate is rendered.
|
||||
|
||||
use std::fmt;
|
||||
use std::local_data;
|
||||
use std::io;
|
||||
use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
|
||||
use std::str;
|
||||
use std::slice;
|
||||
use collections::{HashMap, HashSet};
|
||||
use std::fmt;
|
||||
use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
|
||||
use std::io;
|
||||
use std::local_data;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use std::strbuf::StrBuf;
|
||||
|
||||
use sync::Arc;
|
||||
use serialize::json::ToJson;
|
||||
|
|
@ -71,7 +72,7 @@ pub struct Context {
|
|||
pub current: Vec<~str> ,
|
||||
/// String representation of how to get back to the root path of the 'doc/'
|
||||
/// folder in terms of a relative URL.
|
||||
pub root_path: ~str,
|
||||
pub root_path: StrBuf,
|
||||
/// The current destination folder of where HTML artifacts should be placed.
|
||||
/// This changes as the context descends into the module hierarchy.
|
||||
pub dst: Path,
|
||||
|
|
@ -209,7 +210,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
|||
let mut cx = Context {
|
||||
dst: dst,
|
||||
current: Vec::new(),
|
||||
root_path: ~"",
|
||||
root_path: StrBuf::new(),
|
||||
sidebar: HashMap::new(),
|
||||
layout: layout::Layout {
|
||||
logo: ~"",
|
||||
|
|
@ -511,7 +512,7 @@ impl<'a> SourceCollector<'a> {
|
|||
|
||||
// Create the intermediate directories
|
||||
let mut cur = self.dst.clone();
|
||||
let mut root_path = ~"../../";
|
||||
let mut root_path = StrBuf::from_str("../../");
|
||||
clean_srcpath(p.dirname(), |component| {
|
||||
cur.push(component);
|
||||
mkdir(&cur).unwrap();
|
||||
|
|
@ -525,7 +526,7 @@ impl<'a> SourceCollector<'a> {
|
|||
let page = layout::Page {
|
||||
title: title,
|
||||
ty: "source",
|
||||
root_path: root_path,
|
||||
root_path: root_path.as_slice(),
|
||||
};
|
||||
try!(layout::render(&mut w as &mut Writer, &self.cx.layout,
|
||||
&page, &(""), &Source(contents)));
|
||||
|
|
@ -826,16 +827,18 @@ impl Context {
|
|||
// does make formatting *a lot* nicer.
|
||||
local_data::set(current_location_key, cx.current.clone());
|
||||
|
||||
let mut title = cx.current.connect("::");
|
||||
let mut title = StrBuf::from_str(cx.current.connect("::"));
|
||||
if pushname {
|
||||
if title.len() > 0 { title.push_str("::"); }
|
||||
if title.len() > 0 {
|
||||
title.push_str("::");
|
||||
}
|
||||
title.push_str(*it.name.get_ref());
|
||||
}
|
||||
title.push_str(" - Rust");
|
||||
let page = layout::Page {
|
||||
ty: shortty(it),
|
||||
root_path: cx.root_path,
|
||||
title: title,
|
||||
root_path: cx.root_path.as_slice(),
|
||||
title: title.as_slice(),
|
||||
};
|
||||
|
||||
markdown::reset_headers();
|
||||
|
|
@ -968,7 +971,7 @@ impl<'a> fmt::Show for Item<'a> {
|
|||
let cur = self.cx.current.as_slice();
|
||||
let amt = if self.ismodule() { cur.len() - 1 } else { cur.len() };
|
||||
for (i, component) in cur.iter().enumerate().take(amt) {
|
||||
let mut trail = ~"";
|
||||
let mut trail = StrBuf::new();
|
||||
for _ in range(0, cur.len() - i - 1) {
|
||||
trail.push_str("../");
|
||||
}
|
||||
|
|
@ -1002,10 +1005,10 @@ fn item_path(item: &clean::Item) -> ~str {
|
|||
}
|
||||
|
||||
fn full_path(cx: &Context, item: &clean::Item) -> ~str {
|
||||
let mut s = cx.current.connect("::");
|
||||
let mut s = StrBuf::from_str(cx.current.connect("::"));
|
||||
s.push_str("::");
|
||||
s.push_str(item.name.get_ref().as_slice());
|
||||
return s;
|
||||
return s.into_owned();
|
||||
}
|
||||
|
||||
fn blank<'a>(s: Option<&'a str>) -> &'a str {
|
||||
|
|
@ -1203,7 +1206,7 @@ fn item_function(w: &mut Writer, it: &clean::Item,
|
|||
|
||||
fn item_trait(w: &mut Writer, it: &clean::Item,
|
||||
t: &clean::Trait) -> fmt::Result {
|
||||
let mut parents = ~"";
|
||||
let mut parents = StrBuf::new();
|
||||
if t.parents.len() > 0 {
|
||||
parents.push_str(": ");
|
||||
for (i, p) in t.parents.iter().enumerate() {
|
||||
|
|
@ -1677,7 +1680,9 @@ impl<'a> fmt::Show for Sidebar<'a> {
|
|||
try!(write!(fmt.buf, "&\\#8203;::"));
|
||||
}
|
||||
try!(write!(fmt.buf, "<a href='{}index.html'>{}</a>",
|
||||
cx.root_path.slice_to((cx.current.len() - i - 1) * 3),
|
||||
cx.root_path
|
||||
.as_slice()
|
||||
.slice_to((cx.current.len() - i - 1) * 3),
|
||||
*name));
|
||||
}
|
||||
try!(write!(fmt.buf, "</p>"));
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
//! Table-of-contents creation.
|
||||
|
||||
use std::fmt;
|
||||
use std::strbuf::StrBuf;
|
||||
|
||||
/// A (recursive) table of contents
|
||||
#[deriving(Eq)]
|
||||
|
|
@ -136,11 +137,11 @@ impl TocBuilder {
|
|||
{
|
||||
let (toc_level, toc) = match self.chain.last() {
|
||||
None => {
|
||||
sec_number = ~"";
|
||||
sec_number = StrBuf::new();
|
||||
(0, &self.top_level)
|
||||
}
|
||||
Some(entry) => {
|
||||
sec_number = entry.sec_number.clone();
|
||||
sec_number = StrBuf::from_str(entry.sec_number.clone());
|
||||
sec_number.push_str(".");
|
||||
(entry.level, &entry.children)
|
||||
}
|
||||
|
|
@ -156,12 +157,12 @@ impl TocBuilder {
|
|||
}
|
||||
|
||||
self.chain.push(TocEntry {
|
||||
level: level,
|
||||
name: name,
|
||||
sec_number: sec_number,
|
||||
id: id,
|
||||
children: Toc { entries: Vec::new() }
|
||||
});
|
||||
level: level,
|
||||
name: name,
|
||||
sec_number: sec_number.into_owned(),
|
||||
id: id,
|
||||
children: Toc { entries: Vec::new() }
|
||||
});
|
||||
|
||||
// get the thing we just pushed, so we can borrow the string
|
||||
// out of it with the right lifetime
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::{str, io};
|
||||
|
||||
use collections::HashSet;
|
||||
use std::{str, io};
|
||||
use std::strbuf::StrBuf;
|
||||
|
||||
use getopts;
|
||||
use testing;
|
||||
|
|
@ -62,12 +62,12 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
|
|||
}
|
||||
|
||||
fn load_external_files(names: &[~str]) -> Option<~str> {
|
||||
let mut out = ~"";
|
||||
let mut out = StrBuf::new();
|
||||
for name in names.iter() {
|
||||
out.push_str(load_or_return!(name.as_slice(), None, None));
|
||||
out.push_char('\n');
|
||||
}
|
||||
Some(out)
|
||||
Some(out.into_owned())
|
||||
}
|
||||
|
||||
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
|
||||
|
|
@ -77,7 +77,7 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
|
|||
output.push(input_p.filestem().unwrap());
|
||||
output.set_extension("html");
|
||||
|
||||
let mut css = ~"";
|
||||
let mut css = StrBuf::new();
|
||||
for name in matches.opt_strs("markdown-css").iter() {
|
||||
let s = format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{}\">\n", name);
|
||||
css.push_str(s)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,13 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::cmp;
|
||||
use collections::HashSet;
|
||||
use rustc::util::nodemap::NodeSet;
|
||||
use std::cmp;
|
||||
use std::local_data;
|
||||
use std::strbuf::StrBuf;
|
||||
use std::uint;
|
||||
use syntax::ast;
|
||||
use rustc::util::nodemap::NodeSet;
|
||||
|
||||
use clean;
|
||||
use clean::Item;
|
||||
|
|
@ -235,7 +236,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
|
|||
struct Collapser;
|
||||
impl fold::DocFolder for Collapser {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
let mut docstr = ~"";
|
||||
let mut docstr = StrBuf::new();
|
||||
let mut i = i;
|
||||
for attr in i.attrs.iter() {
|
||||
match *attr {
|
||||
|
|
@ -250,8 +251,8 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
|
|||
&clean::NameValue(ref x, _) if "doc" == *x => false,
|
||||
_ => true
|
||||
}).map(|x| x.clone()).collect();
|
||||
if "" != docstr {
|
||||
a.push(clean::NameValue(~"doc", docstr));
|
||||
if docstr.len() > 0 {
|
||||
a.push(clean::NameValue(~"doc", docstr.into_owned()));
|
||||
}
|
||||
i.attrs = a;
|
||||
self.fold_item_recur(i)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@
|
|||
|
||||
use clean;
|
||||
|
||||
use serialize::json;
|
||||
use dl = std::unstable::dynamic_lib;
|
||||
use serialize::json;
|
||||
use std::strbuf::StrBuf;
|
||||
|
||||
pub type PluginJson = Option<(~str, json::Json)>;
|
||||
pub type PluginResult = (clean::Crate, PluginJson);
|
||||
|
|
@ -70,21 +71,23 @@ impl PluginManager {
|
|||
}
|
||||
|
||||
#[cfg(target_os="win32")]
|
||||
fn libname(mut n: ~str) -> ~str {
|
||||
fn libname(n: ~str) -> ~str {
|
||||
let mut n = StrBuf::from_owned_str(n);
|
||||
n.push_str(".dll");
|
||||
n
|
||||
n.into_owned()
|
||||
}
|
||||
|
||||
#[cfg(target_os="macos")]
|
||||
fn libname(mut n: ~str) -> ~str {
|
||||
fn libname(n: ~str) -> ~str {
|
||||
let mut n = StrBuf::from_owned_str(n);
|
||||
n.push_str(".dylib");
|
||||
n
|
||||
n.into_owned()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os="win32"), not(target_os="macos"))]
|
||||
fn libname(n: ~str) -> ~str {
|
||||
let mut i = ~"lib";
|
||||
let mut i = StrBuf::from_str("lib");
|
||||
i.push_str(n);
|
||||
i.push_str(".so");
|
||||
i
|
||||
i.into_owned()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use std::io::{Process, TempDir};
|
|||
use std::local_data;
|
||||
use std::os;
|
||||
use std::str;
|
||||
use std::strbuf::StrBuf;
|
||||
|
||||
use collections::HashSet;
|
||||
use testing;
|
||||
|
|
@ -167,10 +168,10 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
|
|||
}
|
||||
|
||||
fn maketest(s: &str, cratename: &str, loose_feature_gating: bool) -> ~str {
|
||||
let mut prog = ~r"
|
||||
#![deny(warnings)]
|
||||
#![allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)]
|
||||
";
|
||||
let mut prog = StrBuf::from_str(r"
|
||||
#![deny(warnings)];
|
||||
#![allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)];
|
||||
");
|
||||
|
||||
if loose_feature_gating {
|
||||
// FIXME #12773: avoid inserting these when the tutorial & manual
|
||||
|
|
@ -191,7 +192,7 @@ fn maketest(s: &str, cratename: &str, loose_feature_gating: bool) -> ~str {
|
|||
prog.push_str("\n}");
|
||||
}
|
||||
|
||||
return prog;
|
||||
return prog.into_owned();
|
||||
}
|
||||
|
||||
pub struct Collector {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue