Closes #11362.
Vivek Galatage <vivekgalatage@gmail.com>
Volker Mische <volker.mische@gmail.com>
Wade Mealing <wmealing@gmail.com>
-William Ting <william.h.ting@gmail.com>
+William Ting <io@williamting.com>
Yasuhiro Fujii <y-fujii@mimosa-pudica.net>
Young-il Choi <duddlf.choi@samsung.com>
Youngmin Yoo <youngmin.yoo@samsung.com>
Use [`File::open`](http://static.rust-lang.org/doc/master/std/io/fs/struct.File.html#method.open) to create a [`File`](http://static.rust-lang.org/doc/master/std/io/fs/struct.File.html) struct, which implements the [`Reader`](http://static.rust-lang.org/doc/master/std/io/trait.Reader.html) trait.
-~~~ {.xfail-test}
+~~~ {.ignore}
use std::path::Path;
use std::io::fs::File;
Attempting to close a closed door is prevented statically:
-~~~ {.xfail-test}
+~~~ {.ignore}
let _ = close(Door::<Closed>(~"front")); // error: mismatched types: expected `main::Door<main::Open>` but found `main::Door<main::Closed>`
~~~
You can use a zero-element `enum` ([phantom type](#how-do-i-express-phantom-types)) to represent the opaque object handle. The FFI would look like this:
-~~~ {.xfail-test}
+~~~ {.ignore}
enum Window {}
extern "C" {
fn createWindow(width: c_int, height: c_int) -> *Window;
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
use std::io::{BufferedReader, File};
# mod BufferedReader {
# use std::io::File;
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
use std::io::{BufferedReader, File};
use std::task;
# mod BufferedReader {
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
use std::io::{BufferedReader, File};
# mod BufferedReader {
# use std::io::File;
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
use std::io::{BufferedReader, File};
# mod BufferedReader {
# use std::io::File;
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
use std::io::{BufferedReader, File};
# mod BufferedReader {
# use std::io::File;
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
-use std::io::File;
+use std::io::{BufferedReader, File};
# mod BufferedReader {
# use std::io::File;
# use std::io::MemReader;
~~~~
# #[allow(unused_imports)];
-# extern mod extra;
use std::io::{BufferedReader, File};
# mod BufferedReader {
# use std::io::File;
implementing the `FromIterator` trait. For example, the implementation for
vectors is as follows:
-~~~ {.xfail-test}
+~~~ {.ignore}
impl<A> FromIterator<A> for ~[A] {
pub fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
let (lower, _) = iterator.size_hint();
The `Iterator` trait provides a `size_hint` default method, returning a lower
bound and optionally on upper bound on the length of the iterator:
-~~~ {.xfail-test}
+~~~ {.ignore}
fn size_hint(&self) -> (uint, Option<uint>) { (0, None) }
~~~
The following is a minimal example of calling a foreign function which will
compile if snappy is installed:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
use std::libc::size_t;
#[link(name = "snappy")]
The `extern` block can be extended to cover the entire snappy API:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
use std::libc::{c_int, size_t};
#[link(name = "snappy")]
length is number of elements currently contained, and the capacity is the total size in elements of
the allocated memory. The length is less than or equal to the capacity.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
unsafe {
snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0
`snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
the true length after compression for setting the length.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
pub fn compress(src: &[u8]) -> ~[u8] {
unsafe {
let srclen = src.len() as size_t;
Decompression is similar, because snappy stores the uncompressed size as part of the compression
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
unsafe {
let srclen = src.len() as size_t;
A basic example is:
Rust code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
extern fn callback(a:i32) {
println!("I'm called from C with value {0}", a);
}
~~~~
C code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
typedef void (*rust_callback)(int32_t);
rust_callback cb;
referenced Rust object.
Rust code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
struct RustObject {
a: i32,
~~~~
C code:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
typedef void (*rust_callback)(int32_t);
void* cb_target;
rust_callback cb;
specifies raw flags which need to get passed to the linker when producing an
artifact. An example usage would be:
-~~~ {.xfail-test}
+~~~ {.ignore}
#[link_args = "-foo -bar -baz"]
extern {}
~~~
global state. In order to access these variables, you declare them in `extern`
blocks with the `static` keyword:
-~~~{.xfail-test}
+~~~{.ignore}
use std::libc;
#[link(name = "readline")]
interface. To do this, statics can be declared with `mut` so rust can mutate
them.
-~~~{.xfail-test}
+~~~{.ignore}
use std::libc;
use std::ptr;
scope_. Therefore, a program like this is illegal (and would be
rejected by the compiler):
-~~~ {.xfail-test}
+~~~ {.ignore}
fn example3() -> int {
let mut x = ~X {f: 3};
let y = &x.f;
and structs, and the compiler will still be able to detect possible
mutations:
-~~~ {.xfail-test}
+~~~ {.ignore}
fn example3() -> int {
struct R { g: int }
struct S { f: ~R }
To emphasize this point, let’s look at a variation on the example, this
time one that does not compile:
-~~~ {.xfail-test}
+~~~ {.ignore}
struct Point {x: f64, y: f64}
fn get_x_sh(p: @Point) -> &f64 {
&p.x // Error reported here
So I wrote this code to try it out:
-~~~rust{.xfail-test}
+~~~rust{.ignore}
fn main() {
let number = 5;
let succ_number = succ(number);
For example, let's say you're using an owned pointer, and you want to do this:
-~~~rust{.xfail-test}
+~~~rust{.ignore}
struct Point {
x: int,
y: int,
'lifetimes'. Here's the simple explanation: would you expect this code to
compile?
-~~~rust{.xfail-test}
+~~~rust{.ignore}
fn main() {
println!("{}", x);
let x = 5;
is able to determine that that pointer will go out of scope without `x` being
mutated, and therefore, lets us pass. This wouldn't work:
-~~~rust{.xfail-test}
+~~~rust{.ignore}
fn main() {
let mut x = ~5;
if *x < 10 {
`Port`. What if our example needed to compute multiple results across a number
of tasks? The following program is ill-typed:
-~~~ {.xfail-test}
+~~~ {.ignore}
# use std::task::{spawn};
# fn some_expensive_computation() -> int { 42 }
let (port, chan) = Chan::new();
field (representing a successful result) or an `Err` result (representing
termination with an error).
-~~~{.xfail-test .linked-failure}
+~~~{.ignore .linked-failure}
# use std::task;
# fn some_condition() -> bool { false }
# fn calculate_result() -> int { 0 }
the string in response. The child terminates when it receives `0`.
Here is the function that implements the child task:
-~~~{.xfail-test .linked-failure}
+~~~{.ignore .linked-failure}
# use extra::comm::DuplexStream;
# use std::uint;
fn stringifier(channel: &DuplexStream<~str, uint>) {
Here is the code for the parent task:
-~~~{.xfail-test .linked-failure}
+~~~{.ignore .linked-failure}
# use std::task::spawn;
# use std::uint;
# use extra::comm::DuplexStream;
#: doc/complement-cheatsheet.md:54
#, fuzzy
#| msgid "~~~~ use std::task::spawn;"
-msgid "~~~ {.xfail-test} use std::path::Path; use std::io::fs::File;"
+msgid "~~~ {.ignore} use std::path::Path; use std::io::fs::File;"
msgstr ""
"~~~~\n"
"use std::task::spawn;"
#: doc/guide-ffi.md:16
#, fuzzy
#| msgid "~~~~ use std::task::spawn;"
-msgid "~~~~ {.xfail-test} use std::libc::size_t;"
+msgid "~~~~ {.ignore} use std::libc::size_t;"
msgstr ""
"~~~~\n"
"use std::task::spawn;"
#: doc/guide-ffi.md:48
#, fuzzy
#| msgid "~~~~ use std::task::spawn;"
-msgid "~~~~ {.xfail-test} use std::libc::{c_int, size_t};"
+msgid "~~~~ {.ignore} use std::libc::{c_int, size_t};"
msgstr ""
"~~~~\n"
"use std::task::spawn;"
#: doc/guide-ffi.md:344
#, fuzzy
#| msgid "~~~~ use std::task::spawn;"
-msgid "~~~{.xfail-test} use std::libc;"
+msgid "~~~{.ignore} use std::libc;"
msgstr ""
"~~~~\n"
"use std::task::spawn;"
#: doc/guide-ffi.md:363
#, fuzzy
#| msgid "~~~~ use std::task::spawn;"
-msgid "~~~{.xfail-test} use std::libc; use std::ptr;"
+msgid "~~~{.ignore} use std::libc; use std::ptr;"
msgstr ""
"~~~~\n"
"use std::task::spawn;"
#. type: Plain text
#: doc/guide-lifetimes.md:48
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"~~~\n"
"# struct Point {x: f64, y: f64}\n"
"let owned_box : ~Point = ~Point {x: 7.0, y: 9.0};\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-lifetimes.md:82
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"~~~\n"
"# struct Point {x: f64, y: f64}\n"
"compute_distance(managed_box, owned_box);\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:115
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let p0 = Point { x: 5, y: 10};\n"
" println!(\"{:?}\", p1);\n"
"}\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:129
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"~~~rust\n"
"# struct Point {\n"
" Point { x: p.x + 1, y: p.y + 1}\n"
"}\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:145
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn transform(p: Point) -> Point {\n"
" Point { x: p.x + 1, y: p.y + 1}\n"
"}\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:152
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let p0 = Point { x: 5, y: 10};\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:229
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let a = Point { x: 10, y: 20 };\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:246
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let a = ~Point { x: 10, y: 20 };\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:277
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let a = ~Point { x: 10, y: 20 };\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:308
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let a = @Point { x: 10, y: 20 };\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:352
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"fn main() {\n"
" let origin = @Point { x: 0.0, y: 0.0 };\n"
" let p1 = ~Point { x: 5.0, y: 3.0 };\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/guide-pointers.md:378
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
-"~~~rust{.xfail-test}\n"
+"~~~rust{.ignore}\n"
"fn main() {\n"
" println!(\"{}\", x);\n"
" let x = 5;\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/guide-rustpkg.md:22
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"fn main() {\n"
" hello::world();\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/guide-rustpkg.md:149
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"pub fn world() {\n"
" println!(\"Hello, world.\");\n"
"}\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#: doc/rust.md:788
#, fuzzy
#| msgid "~~~~ {.ignore} let foo = 10;"
-msgid "~~~~ {.xfail-test} extern mod pcre;"
+msgid "~~~~ {.ignore} extern mod pcre;"
msgstr ""
"~~~~ {.ignore}\n"
"let foo = 10;"
#: doc/rust.md:1395
#, fuzzy
#| msgid ""
-#| "~~~ {.xfail-test} use std::f64::consts::pi; # trait Shape { fn "
+#| "~~~ {.ignore} use std::f64::consts::pi; # trait Shape { fn "
#| "area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } "
#| "# struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, "
#| "radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 "
#| "{ (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn "
#| "area(&self) -> f64 { pi * square(self.radius) } }"
msgid ""
-"~~~~ {.xfail-test} # trait Shape { fn area(&self) -> f64; } # trait Circle : "
+"~~~~ {.ignore} # trait Shape { fn area(&self) -> f64; } # trait Circle : "
"Shape { fn radius(&self) -> f64; } # impl Shape for int { fn area(&self) -> "
"f64 { 0.0 } } # impl Circle for int { fn radius(&self) -> f64 { 0.0 } } # "
"let mycircle = 0;"
msgstr ""
-"~~~ {.xfail-test}\n"
+"~~~ {.ignore}\n"
"use std::f64::consts::pi;\n"
"# trait Shape { fn area(&self) -> f64; }\n"
"# trait Circle : Shape { fn radius(&self) -> f64; }\n"
#: doc/rust.md:2400
#, fuzzy
#| msgid "~~~~ use std::task::spawn;"
-msgid "~~~~ {.xfail-test} # use std::task; # do task::spawn {"
+msgid "~~~~ {.ignore} # use std::task; # do task::spawn {"
msgstr ""
"~~~~\n"
"use std::task::spawn;"
#. type: Plain text
#: doc/rust.md:3299
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"fn main() {\n"
" print(@10 as @Printable);\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:136
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"~~~~\n"
"fn main() {\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:604
msgid ""
-"~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point "
+"~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point "
"{ x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/tutorial.md:1372
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"~~~\n"
"# struct Point { x: f64, y: f64 }\n"
"let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 };\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#. type: Plain text
#: doc/tutorial.md:1404
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
+#| msgid "~~~~ {.ignore} # struct Point { x: f64, y: f64 } let mut mypoint = Point { x: 1.0, y: 1.0 }; let origin = Point { x: 0.0, y: 0.0 };"
msgid ""
"~~~\n"
"# struct Point{ x: f64, y: f64 };\n"
"compute_distance(managed_box, owned_box);\n"
"~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"# struct Point { x: f64, y: f64 }\n"
"let mut mypoint = Point { x: 1.0, y: 1.0 };\n"
"let origin = Point { x: 0.0, y: 0.0 };"
#: doc/tutorial.md:2067
#, no-wrap
msgid ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// This does not compile\n"
"fn head_bad<T>(v: &[T]) -> T {\n"
" v[0] // error: copying a non-copyable value\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// このコードはコンパイルできない\n"
"fn head_bad<T>(v: &[T]) -> T {\n"
" v[0] // error: copying a non-copyable value\n"
#. type: Plain text
#: doc/tutorial.md:2148
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"~~~~\n"
"trait Printable {\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:2488
#, fuzzy, no-wrap
-#| msgid "~~~ {.xfail-test} use std::f64::consts::pi; # trait Shape { fn area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } # struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { pi * square(self.radius) } }"
+#| msgid "~~~ {.ignore} use std::f64::consts::pi; # trait Shape { fn area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } # struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { pi * square(self.radius) } }"
msgid ""
"~~~~\n"
"use std::f64::consts::PI;\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~ {.xfail-test}\n"
+"~~~ {.ignore}\n"
"use std::f64::consts::pi;\n"
"# trait Shape { fn area(&self) -> f64; }\n"
"# trait Circle : Shape { fn radius(&self) -> f64; }\n"
#: doc/tutorial.md:2517
#, fuzzy
#| msgid ""
-#| "~~~ {.xfail-test} use std::f64::consts::pi; # trait Shape { fn "
+#| "~~~ {.ignore} use std::f64::consts::pi; # trait Shape { fn "
#| "area(&self) -> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } "
#| "# struct Point { x: f64, y: f64 } # struct CircleStruct { center: Point, "
#| "radius: f64 } # impl Circle for CircleStruct { fn radius(&self) -> f64 "
#| "{ (self.area() / pi).sqrt() } } # impl Shape for CircleStruct { fn "
#| "area(&self) -> f64 { pi * square(self.radius) } }"
msgid ""
-"~~~ {.xfail-test} use std::f64::consts::PI; # trait Shape { fn area(&self) -"
+"~~~ {.ignore} use std::f64::consts::PI; # trait Shape { fn area(&self) -"
"> f64; } # trait Circle : Shape { fn radius(&self) -> f64; } # struct Point "
"{ x: f64, y: f64 } # struct CircleStruct { center: Point, radius: f64 } # "
"impl Circle for CircleStruct { fn radius(&self) -> f64 { (self.area() / PI)."
"sqrt() } } # impl Shape for CircleStruct { fn area(&self) -> f64 { PI * "
"square(self.radius) } }"
msgstr ""
-"~~~ {.xfail-test}\n"
+"~~~ {.ignore}\n"
"use std::f64::consts::pi;\n"
"# trait Shape { fn area(&self) -> f64; }\n"
"# trait Circle : Shape { fn radius(&self) -> f64; }\n"
#. type: Plain text
#: doc/tutorial.md:2567
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"~~~~\n"
"// main.rs\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:2600
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"fn main() {\n"
" println!(\"Hello farm!\");\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:2620
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"fn main() {\n"
" println!(\"Hello chicken!\");\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:2732
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"fn main() {\n"
" println!(\"Hello farm!\");\n"
"}\n"
"~~~~\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#. type: Plain text
#: doc/tutorial.md:2929
#, fuzzy, no-wrap
-#| msgid "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
+#| msgid "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~\"hello \" + world::explore()); } ~~~~"
msgid ""
"fn main() {\n"
" println!(\"Hello farm!\");\n"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
#: doc/tutorial.md:3144
#, fuzzy
#| msgid ""
-#| "~~~~ {.xfail-test} extern mod farm; extern mod my_farm (name = \"farm\", "
+#| "~~~~ {.ignore} extern mod farm; extern mod my_farm (name = \"farm\", "
#| "vers = \"2.5\"); extern mod my_auxiliary_farm (name = \"farm\", author = "
#| "\"mjh\"); ~~~~"
msgid ""
-"~~~~ {.xfail-test} extern mod farm; extern mod farm = \"farm#2.5\"; extern "
+"~~~~ {.ignore} extern mod farm; extern mod farm = \"farm#2.5\"; extern "
"mod my_farm = \"farm\"; ~~~~"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"extern mod farm;\n"
"extern mod my_farm (name = \"farm\", vers = \"2.5\");\n"
"extern mod my_auxiliary_farm (name = \"farm\", author = \"mjh\");\n"
#: doc/tutorial.md:3185
#, fuzzy
#| msgid ""
-#| "~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println(~"
+#| "~~~~ {.ignore} // main.rs extern mod world; fn main() { println(~"
#| "\"hello \" + world::explore()); } ~~~~"
msgid ""
-"~~~~ {.xfail-test} // main.rs extern mod world; fn main() { println!(\"hello "
+"~~~~ {.ignore} // main.rs extern mod world; fn main() { println!(\"hello "
"{}\", world::explore()); } ~~~~"
msgstr ""
-"~~~~ {.xfail-test}\n"
+"~~~~ {.ignore}\n"
"// main.rs\n"
"extern mod world;\n"
"fn main() { println(~\"hello \" + world::explore()); }\n"
When a nested submodule is loaded from an external file,
it is loaded from a subdirectory path that mirrors the module hierarchy.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
// Load the `vec` module from `vec.rs`
mod vec;
The directories and files used for loading external file modules can be influenced
with the `path` attribute.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[path = "task_files"]
mod task {
// Load the `local_data` module from `task_files/tls.rs`
Four examples of `extern mod` declarations:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
extern mod pcre;
extern mod extra; // equivalent to: extern mod extra = "extra";
declared, in an angle-bracket-enclosed, comma-separated list following
the function name.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
fn iter<T>(seq: &[T], f: |T|) {
for elt in seq.iter() { f(elt); }
}
Likewise, supertrait methods may also be called on trait objects.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
# trait Shape { fn area(&self) -> f64; }
# trait Circle : Shape { fn radius(&self) -> f64; }
# impl Shape for int { fn area(&self) -> f64 { 0.0 } }
uses the standard C "cdecl" ABI. Other ABIs may be specified using
an `abi` string, as shown here:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
// Interface to the Windows API
extern "stdcall" { }
~~~~
specified the compiler will attempt to link against the native library of the
specified name.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[link(name = "crypto")]
extern { }
~~~~
An example of attributes:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
// General metadata applied to the enclosing module or crate.
#[license = "BSD"];
The lint checks supported by the compiler can be found via `rustc -W help`,
along with their default settings.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
mod m1 {
// Missing documentation is ignored here
#[allow(missing_doc)]
This example shows how one can use `allow` and `warn` to toggle
a particular check on and off.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[warn(missing_doc)]
mod m2{
#[allow(missing_doc)]
This example shows how one can use `forbid` to disallow uses
of `allow` for that lint check.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[forbid(missing_doc)]
mod m3 {
// Attempting to toggle warning signals an error here
The `lang` attribute makes it possible to declare these operations.
For example, the `str` module in the Rust standard library defines the string equality function:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[lang="str_eq"]
pub fn eq_slice(a: &str, b: &str) -> bool {
// details elided
be unstable for the purposes of the lint. One can give an optional
string that will be displayed when the lint flags the use of an item.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[warn(unstable)];
#[deprecated="replaced by `best`"]
For this reason, rust recognizes a special crate-level attribute of the form:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
#[feature(feature1, feature2, feature3)]
~~~~
is bounds-checked at run-time. When the check fails, it will put the
task in a _failing state_.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
# use std::task;
# do task::spawn {
`mypoint.y += 1.0`. But in an immutable location, such an assignment to a
struct without inherited mutability would result in a type error.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
# struct Point { x: f64, y: f64 }
let mut mypoint = Point { x: 1.0, y: 1.0 };
let origin = Point { x: 0.0, y: 0.0 };
a `List` type as being *either* the end of the list (`Nil`) or another node
(`Cons`). The full definition of the `Cons` variant will require some thought.
-~~~ {.xfail-test}
+~~~ {.ignore}
enum List {
Cons(...), // an incomplete definition of the next element in a List
Nil // the end of a List
The obvious approach is to define `Cons` as containing an element in the list
along with the next `List` node. However, this will generate a compiler error.
-~~~ {.xfail-test}
+~~~ {.ignore}
// error: illegal recursive enum type; wrap the inner value in a box to make it representable
enum List {
Cons(u32, List), // an element (`u32`) and the next node in the list
The `clone` method is provided by the `Clone` trait, and can be derived for
our `List` type. Traits will be explained in detail later.
-~~~{.xfail-test}
+~~~{.ignore}
#[deriving(Clone)]
enum List {
Cons(u32, ~List),
The obvious signature for a `List` equality comparison is the following:
-~~~{.xfail-test}
+~~~{.ignore}
fn eq(xs: List, ys: List) -> bool { ... }
~~~
isn't required to compare the lists, so the function should take *references*
(&T) instead.
-~~~{.xfail-test}
+~~~{.ignore}
fn eq(xs: &List, ys: &List) -> bool { ... }
~~~
methods. The absence of a `self` parameter distinguishes such methods.
These methods are the preferred way to define constructor functions.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
impl Circle {
fn area(&self) -> f64 { ... }
fn new(area: f64) -> Circle { ... }
In Rust, we can't,
and if we try to run the following code the compiler will complain.
-~~~~ {.xfail-test}
+~~~~ {.ignore}
// This does not compile
fn head_bad<T>(v: &[T]) -> T {
v[0] // error: copying a non-copyable value
Likewise, supertrait methods may also be called on trait objects.
-~~~ {.xfail-test}
+~~~ {.ignore}
use std::f64::consts::PI;
# trait Shape { fn area(&self) -> f64; }
# trait Circle : Shape { fn radius(&self) -> f64; }
We've now defined a nice module hierarchy. But how do we access the items in it from our `main` function?
One way to do it is to simply fully qualifying it:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
mod farm {
fn chicken() { println!("cluck cluck"); }
// ...
example, these `extern mod` statements would both accept and select the
crate define above:
-~~~~ {.xfail-test}
+~~~~ {.ignore}
extern mod farm;
extern mod farm = "farm#2.5";
extern mod my_farm = "farm";
# fn main() {}
~~~~
-~~~~ {.xfail-test}
+~~~~ {.ignore}
// main.rs
extern mod world;
fn main() { println!("hello {}", world::explore()); }
# xfail-license
+# -*- coding: utf-8 -*-
+"""
+Script for extracting compilable fragments from markdown documentation. See
+prep.js for a description of the format recognized by this tool. Expects
+a directory fragments/ to exist under the current directory, and writes the
+fragments in there as individual .rs files.
+"""
+from __future__ import print_function
+from codecs import open
+from collections import deque
+from itertools import imap
+import os
+import re
+import sys
-# Script for extracting compilable fragments from markdown
-# documentation. See prep.js for a description of the format
-# recognized by this tool. Expects a directory fragments/ to exist
-# under the current directory, and writes the fragments in there as
-# individual .rs files.
-
-import sys, re
-
-if len(sys.argv) < 3:
- print("Please provide an input filename")
- sys.exit(1)
-
-filename = sys.argv[1]
-dest = sys.argv[2]
-f = open(filename)
-lines = f.readlines()
-f.close()
-
-cur = 0
-line = ""
-chapter = ""
-chapter_n = 0
-
-while cur < len(lines):
- line = lines[cur]
- cur += 1
- chap = re.match("# (.*)", line)
- if chap:
- chapter = re.sub(r"\W", "_", chap.group(1)).lower()
- chapter_n = 1
- elif re.match("~~~", line):
- # Parse the tags that open a code block in the pandoc format:
- # ~~~ {.tag1 .tag2}
- tags = re.findall("\.([\w-]*)", line)
- block = ""
- ignore = "notrust" in tags or "ignore" in tags
- # Some tags used by the language ref that indicate not rust
- ignore |= "ebnf" in tags
- ignore |= "abnf" in tags
- ignore |= "keyword" in tags
- ignore |= "field" in tags
- ignore |= "precedence" in tags
- xfail = "xfail-test" in tags
- while cur < len(lines):
- line = lines[cur]
- cur += 1
- if re.match("~~~", line):
- break
- else:
- # Lines beginning with '# ' are turned into valid code
- line = re.sub("^# ", "", line)
- # Allow ellipses in code snippets
- line = re.sub("\.\.\.", "", line)
- block += line
- if not ignore:
- if not re.search(r"\bfn main\b", block):
- block = "fn main() {\n" + block + "\n}\n"
- if not re.search(r"\bextern mod extra\b", block):
- block = "extern mod extra;\n" + block
- block = """#[ deny(warnings) ];
-#[ allow(unused_variable) ];\n
-#[ allow(dead_assignment) ];\n
-#[ allow(unused_mut) ];\n
-#[ allow(attribute_usage) ];\n
-#[ allow(dead_code) ];\n
-#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n
-""" + block
- if xfail:
- block = "// xfail-test\n" + block
- filename = (dest + "/" + str(chapter)
- + "_" + str(chapter_n) + ".rs")
- chapter_n += 1
- f = open(filename, 'w')
- f.write(block)
- f.close()
+# regexes
+CHAPTER_NAME_REGEX = re.compile(r'# (.*)')
+CODE_BLOCK_DELIM_REGEX = re.compile(r'~~~')
+COMMENT_REGEX = re.compile(r'^# ')
+COMPILER_DIRECTIVE_REGEX = re.compile(r'\#\[(.*)\];')
+ELLIPSES_REGEX = re.compile(r'\.\.\.')
+EXTERN_MOD_REGEX = re.compile(r'\bextern mod extra\b')
+MAIN_FUNCTION_REGEX = re.compile(r'\bfn main\b')
+TAGS_REGEX = re.compile(r'\.([\w-]*)')
+
+# tags to ignore
+IGNORE_TAGS = \
+ frozenset(["abnf", "ebnf", "field", "keyword", "notrust", "precedence"])
+
+# header for code snippet files
+OUTPUT_BLOCK_HEADER = '\n'.join((
+ "#[ deny(warnings) ];",
+ "#[ allow(unused_variable) ];",
+ "#[ allow(dead_assignment) ];",
+ "#[ allow(unused_mut) ];",
+ "#[ allow(attribute_usage) ];",
+ "#[ allow(dead_code) ];",
+ "#[ feature(macro_rules, globs, struct_variant, managed_boxes) ];\n",))
+
+
+def add_extern_mod(block):
+ if not has_extern_mod(block):
+ # add `extern mod extra;` after compiler directives
+ directives = []
+ while len(block) and is_compiler_directive(block[0]):
+ directives.append(block.popleft())
+
+ block.appendleft("\nextern mod extra;\n\n")
+ block.extendleft(reversed(directives))
+
+ return block
+
+
+def add_main_function(block):
+ if not has_main_function(block):
+ prepend_spaces = lambda x: ' ' + x
+ block = deque(imap(prepend_spaces, block))
+ block.appendleft("\nfn main() {\n")
+ block.append("\n}\n")
+ return block
+
+
+def extract_code_fragments(dest_dir, lines):
+ """
+ Extracts all the code fragments from a file that do not have ignored tags
+ writing them to the following file:
+
+ [dest dir]/[chapter name]_[chapter_index].rs
+ """
+ chapter_name = None
+ chapter_index = 0
+
+ for line in lines:
+ if is_chapter_title(line):
+ chapter_name = get_chapter_name(line)
+ chapter_index = 1
+ continue
+
+ if not is_code_block_delim(line):
+ continue
+
+ assert chapter_name, "Chapter name missing for code block."
+ tags = get_tags(line)
+ block = get_code_block(lines)
+
+ if tags & IGNORE_TAGS:
+ continue
+
+ block = add_extern_mod(add_main_function(block))
+ block.appendleft(OUTPUT_BLOCK_HEADER)
+
+ if "ignore" in tags:
+ block.appendleft("//xfail-test\n")
+ elif "should_fail" in tags:
+ block.appendleft("//should-fail\n")
+
+ output_filename = os.path.join(
+ dest_dir,
+ chapter_name + '_' + str(chapter_index) + '.rs')
+
+ write_file(output_filename, block)
+ chapter_index += 1
+
+
+def has_extern_mod(block):
+ """Checks if a code block has the line `extern mod extra`."""
+ find_extern_mod = lambda x: re.search(EXTERN_MOD_REGEX, x)
+ return any(imap(find_extern_mod, block))
+
+
+def has_main_function(block):
+ """Checks if a code block has a main function."""
+ find_main_fn = lambda x: re.search(MAIN_FUNCTION_REGEX, x)
+ return any(imap(find_main_fn, block))
+
+
+def is_chapter_title(line):
+ return re.match(CHAPTER_NAME_REGEX, line)
+
+
+def is_code_block_delim(line):
+ return re.match(CODE_BLOCK_DELIM_REGEX, line)
+
+
+def is_compiler_directive(line):
+ return re.match(COMPILER_DIRECTIVE_REGEX, line)
+
+
+def get_chapter_name(line):
+ """Get the chapter name from a `# Containers` line."""
+ return re.sub(
+ r'\W',
+ '_',
+ re.match(CHAPTER_NAME_REGEX, line).group(1)).lower()
+
+
+def get_code_block(lines):
+ """
+ Get a code block surrounded by ~~~, for example:
+
+ 1: ~~~ { .tag }
+ 2: let u: ~[u32] = ~[0, 1, 2];
+ 3: let v: &[u32] = &[0, 1, 2, 3];
+ 4: let w: [u32, .. 5] = [0, 1, 2, 3, 4];
+ 5:
+ 6: println!("u: {}, v: {}, w: {}", u.len(), v.len(), w.len());
+ 7: ~~~
+
+ Returns lines 2-6. Assumes line 1 has been consumed by the caller.
+ """
+ strip_comments = lambda x: re.sub(COMMENT_REGEX, '', x)
+ strip_ellipses = lambda x: re.sub(ELLIPSES_REGEX, '', x)
+
+ result = deque()
+
+ for line in lines:
+ if is_code_block_delim(line):
+ break
+ result.append(strip_comments(strip_ellipses(line)))
+ return result
+
+
+def get_lines(filename):
+ with open(filename) as f:
+ for line in f:
+ yield line
+
+
+def get_tags(line):
+ """
+ Retrieves all tags from the line format:
+ ~~~ { .tag1 .tag2 .tag3 }
+ """
+ return set(re.findall(TAGS_REGEX, line))
+
+
+def write_file(filename, lines):
+ with open(filename, 'w', encoding='utf-8') as f:
+ for line in lines:
+ f.write(unicode(line, encoding='utf-8', errors='replace'))
+
+
+def main(argv=None):
+ if not argv:
+ argv = sys.argv
+
+ if len(sys.argv) < 2:
+ sys.stderr.write("Please provide an input filename.")
+ sys.exit(1)
+ elif len(sys.argv) < 3:
+ sys.stderr.write("Please provide a destination directory.")
+ sys.exit(1)
+
+ input_file = sys.argv[1]
+ dest_dir = sys.argv[2]
+
+ if not os.path.exists(input_file):
+ sys.stderr.write("Input file does not exist.")
+ sys.exit(1)
+
+ if not os.path.exists(dest_dir):
+ os.mkdir(dest_dir)
+
+ extract_code_fragments(dest_dir, get_lines(input_file))
+
+
+if __name__ == "__main__":
+ sys.exit(main())